<?php

namespace App\Http\Controllers;

use App\Models\HealthInstitution;
use App\Models\InstitutionPayment;
use App\Models\PaymentConfiguration;
use App\Http\Requests\StoreHealthInstitutionRequest;
use App\Services\PaymentService;
use App\Services\EmailService;
use App\Services\SMSService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Spatie\Permission\Models\Role;
use App\Models\User;

class InstitutionRegistrationController extends Controller
{
    /**
     * Show the multi-step registration form.
     */
    public function create()
    {
        $paymentConfig = PaymentConfiguration::getInstitutionConfig();

        return view('institutions.register', compact('paymentConfig'));
    }

    /**
     * Process the registration with payment.
     */
    public function store(Request $request, PaymentService $paymentService)
    {
        // Step 1: Validate institution details
        $request->validate([
            // Institution Details
            'name' => ['required', 'string', 'max:191'],
            'short_name' => ['required', 'string', 'max:100'],
            'logo' => ['nullable', 'image', 'mimes:jpeg,png,jpg,gif,svg', 'max:2048'],
            'city' => ['required', 'string', 'max:100'],
            'address' => ['required', 'string', 'max:191'],
            'country' => ['required', 'string', 'max:100'],
            'email' => ['required', 'email', 'max:191'],
            'phone' => ['required', 'string', 'max:50'],
            'website_url' => ['nullable', 'url', 'max:191'],
            'description' => ['required', 'string'],
            'services' => ['required', 'array', 'min:1'],
            'services.*' => ['required', 'string', 'max:191'],

            // Account Details
            'account_name' => ['required', 'string', 'max:191'],
            'account_email' => ['required', 'email', 'max:191', 'unique:users,email'],
            'account_phone' => ['required', 'string', 'max:20', 'unique:users,phone'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],

            // Payment Details
            'payment_method' => ['nullable', 'in:mobile,card'],
            'payment_phone' => ['required_if:payment_method,mobile', 'nullable', 'string', 'max:20', 'regex:/^\+?[0-9]{9,15}$/'],
            'card_number'   => ['required_if:payment_method,card', 'nullable', 'string'],
            'card_expiry'   => ['required_if:payment_method,card', 'nullable', 'regex:/^(0[1-9]|1[0-2])\/\d{2}$/'],
            'card_cvv'      => ['required_if:payment_method,card', 'nullable', 'digits_between:3,4'],
            'currency' => ['required', 'in:SSP,USD'],
            'frequency' => ['required', 'in:one_time,monthly,quarterly,biannual,yearly'],
        ]);

        $paymentConfig = PaymentConfiguration::getInstitutionConfig();

        // Check if free listing
        if ($paymentConfig && $paymentConfig->is_free) {
            return $this->createFreeRegistration($request);
        }

        // Get payment amount
        $amount = $paymentConfig ? $paymentConfig->getAmountForCurrency($request->currency) : 0;

        // Create or get user
        $user = User::create([
            'name'     => $request->account_name,
            'email'    => $request->account_email,
            'username' => User::generateUsername($request->account_email),
            'phone'    => $request->account_phone,
            'password' => Hash::make($request->password),
        ]);

        // Assign Health Marketor role
        $marketorRole = Role::where('name', 'Health Marketor')->first();
        if ($marketorRole) {
            $user->assignRole($marketorRole);
        }

        // Handle logo upload
        $logoPath = null;
        if ($request->hasFile('logo')) {
            $logoPath = $request->file('logo')->store('institutions/logos', 'public');
        }

        // Create institution
        $institution = HealthInstitution::create([
            'user_id' => $user->id,
            'name' => $request->name,
            'short_name' => $request->short_name,
            'logo' => $logoPath,
            'city' => $request->city,
            'address' => $request->address,
            'country' => $request->country,
            'email' => $request->email,
            'phone' => $request->phone,
            'website_url' => $request->website_url,
            'description' => $request->description,
            'services' => array_filter($request->services),
            'listing_status' => 'pending_payment',
            'slug' => Str::slug($request->name),
        ]);

        // Initiate payment (mobile or card)
        $reference     = InstitutionPayment::generateReference();
        $paymentMethod = $request->input('payment_method', 'mobile');
        $storedMethod  = $paymentMethod === 'card' ? 'mtn_momo_card' : 'mtn_momo_mobile';

        if ($paymentMethod === 'card') {
            $result = $paymentService->initiateCardCollection(
                cardNumber: $request->card_number ?? '',
                expiry: $request->card_expiry ?? '',
                cvv: $request->card_cvv ?? '',
                amount: $amount,
                reference: $reference,
                payerMessage: "Registration payment for institution: {$institution->name}"
            );
        } else {
            $result = $paymentService->initiateCollection(
                phoneNumber: $request->payment_phone,
                amount: $amount,
                reference: $reference,
                payerMessage: "Registration payment for institution: {$institution->name}"
            );
        }

        // Create payment record
        $payment = InstitutionPayment::create([
            'health_institution_id' => $institution->id,
            'amount' => $amount,
            'currency' => $request->currency,
            'payment_frequency' => $request->frequency,
            'payment_method' => $storedMethod,
            'transaction_id' => $result['transaction_id'] ?? null,
            'reference' => $reference,
            'status' => $result['success'] ? 'pending' : 'failed',
            'phone_number' => $paymentMethod !== 'card' ? $request->payment_phone : null,
        ]);

        // Log in the user
        auth()->login($user);

        if (!$result['success']) {
            return redirect()->route('institutions.register.payment', $institution->slug)
                ->with('error', 'Payment initiation failed: ' . ($result['message'] ?? 'Unknown error'));
        }

        // Send welcome email
        if (app()->bound(EmailService::class)) {
            app(EmailService::class)->sendTemplate(
                $user->email,
                'Welcome to Health Directory',
                'emails.welcome',
                ['userName' => $user->name, 'institution' => $institution]
            );
        }

        return redirect()->route('payments.status', ['payment' => $payment->id, 'type' => 'institution'])
            ->with('info', 'Registration successful! Please complete the payment on your phone.');
    }

    /**
     * Create free registration (no payment required).
     */
    protected function createFreeRegistration(Request $request)
    {
        // Create user
        $user = User::create([
            'name'     => $request->account_name,
            'email'    => $request->account_email,
            'username' => User::generateUsername($request->account_email),
            'phone'    => $request->account_phone,
            'password' => Hash::make($request->password),
        ]);

        // Assign Health Marketor role
        $marketorRole = Role::where('name', 'Health Marketor')->first();
        if ($marketorRole) {
            $user->assignRole($marketorRole);
        }

        // Handle logo upload
        $logoPath = null;
        if ($request->hasFile('logo')) {
            $logoPath = $request->file('logo')->store('institutions/logos', 'public');
        }

        // Create institution
        $institution = HealthInstitution::create([
            'user_id' => $user->id,
            'name' => $request->name,
            'short_name' => $request->short_name,
            'logo' => $logoPath,
            'city' => $request->city,
            'address' => $request->address,
            'country' => $request->country,
            'email' => $request->email,
            'phone' => $request->phone,
            'website_url' => $request->website_url,
            'description' => $request->description,
            'services' => array_filter($request->services),
            'listing_status' => 'published',
            'is_published' => true,
            'payment_status' => 'paid',
            'slug' => Str::slug($request->name),
        ]);

        // Log in the user
        auth()->login($user);

        // Send welcome email
        if (app()->bound(EmailService::class)) {
            app(EmailService::class)->sendTemplate(
                $user->email,
                'Welcome to Health Directory',
                'emails.welcome',
                ['userName' => $user->name, 'institution' => $institution]
            );
        }

        return redirect()->route('dashboard.institutions.index')
            ->with('success', 'Registration successful! Your institution is now published.');
    }

    /**
     * Show payment page for pending institution.
     */
    public function showPayment(string $slug)
    {
        $institution = HealthInstitution::where('slug', $slug)->firstOrFail();
        $paymentConfig = PaymentConfiguration::getInstitutionConfig();

        return view('institutions.register-payment', compact('institution', 'paymentConfig'));
    }

    /**
     * Process payment for pending institution.
     */
    public function processPayment(Request $request, string $slug, PaymentService $paymentService)
    {
        $institution = HealthInstitution::where('slug', $slug)->firstOrFail();

        $request->validate([
            'phone_number' => ['required', 'string', 'max:20', 'regex:/^\+?[0-9]{9,15}$/'],
            'currency' => ['required', 'in:SSP,USD'],
            'frequency' => ['required', 'in:one_time,monthly,quarterly,biannual,yearly'],
        ]);

        $paymentConfig = PaymentConfiguration::getInstitutionConfig();

        if (!$paymentConfig || $paymentConfig->is_free) {
            $institution->update([
                'listing_status' => 'published',
                'is_published' => true,
                'payment_status' => 'paid',
            ]);

            return redirect()->route('dashboard.institutions.index')
                ->with('success', 'Institution published successfully!');
        }

        $amount = $paymentConfig->getAmountForCurrency($request->currency);
        $reference = InstitutionPayment::generateReference();

        $result = $paymentService->initiateCollection(
            phoneNumber: $request->phone_number,
            amount: $amount,
            reference: $reference,
            payerMessage: "Payment for institution listing: {$institution->name}"
        );

        $payment = InstitutionPayment::create([
            'health_institution_id' => $institution->id,
            'amount' => $amount,
            'currency' => $request->currency,
            'payment_frequency' => $request->frequency,
            'payment_method' => 'mtn_momo',
            'transaction_id' => $result['transaction_id'] ?? null,
            'reference' => $reference,
            'status' => $result['success'] ? 'pending' : 'failed',
            'phone_number' => $request->phone_number,
        ]);

        if (!$result['success']) {
            return redirect()->back()
                ->with('error', 'Payment initiation failed: ' . ($result['message'] ?? 'Unknown error'));
        }

        return redirect()->route('payments.status', ['payment' => $payment->id, 'type' => 'institution'])
            ->with('info', 'Payment initiated. Please check your phone for the MTN MoMo prompt.');
    }
}
