<?php

use Carbon\Carbon;
use App\Models\AFAPackage;
use App\Models\AFAPricing;
use Livewire\Volt\Component;
use App\Models\AFAOrderPayment;
use App\Models\AFARegistration;
use App\Models\AgentAFAPricing;
use App\Models\PaymentProvider;
use App\Rules\GhanaPhoneNumber;
use App\Services\MoorleService;
use App\Services\BulkClixService;
use App\Http\Integrations\Imake\MoorlePay;
use App\Http\Integrations\Imake\BulkClixAPI;
use App\Http\Integrations\Imake\Requests\BulkClix\MomoPay;
use App\Http\Integrations\Imake\Requests\BulkClix\SendOTP;
use App\Http\Integrations\Imake\Requests\BulkClix\VerifyOTP;
use App\Http\Integrations\Imake\Requests\MoorlePay\MakePayment;
use App\Http\Integrations\Imake\Requests\MoorlePay\InitiatePayment;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

new class extends Component {
    public $fullname;
    public $phone;
    public $ghana_card;
    public $occupation;
    public $dob;
    public $afa_cost = 0;
    public $afa_price = 0;
    public $afa_profit = 0;

    public $afaPackage;
    public $originalPrice;

    // Payment Properties
    public $paymentNumber = '';
    public $paymentNetwork = '';
    public $currentStep = 1;
    public $otp = '';
    public $otpSent = false;
    public $verificationComplete = false;
    public $uniqueRef = null;
    public $paymentSummary = [];
    public $isProcessing = false;
    public $showPaymentPrompt = false;

    public $agent;

    public $requestId;
    public $ussdCodeForOTP;

    private $paymentProvider;
    private $bulkClixService;
    private $moorleService;

    public function mount($agent)
    {
        $this->agent = $agent;
        $this->getAfaPricing();
        $this->initializeServices();
    }

    private function initializeServices()
    {
        // Re-initialize services if they're null
        if (!$this->bulkClixService) {
            $this->bulkClixService = app(BulkClixService::class);
        }

        if (!$this->moorleService) {
            $this->moorleService = app(MoorleService::class);
        }

        $this->paymentProvider = PaymentProvider::activeProvider();

        Log::info('Services initialized', [
            'moorleService' => $this->moorleService ? get_class($this->moorleService) : 'null',
            'bulkClixService' => $this->bulkClixService ? get_class($this->bulkClixService) : 'null',
        ]);
    }

    public function getAfaPricing()
    {
        $this->afaPackage = AFAPackage::where('status', 'active')->first();
        $pricing = AgentAFAPricing::where('user_id', $this->agent->id)->where('package_id', $this->afaPackage->id)->first();

        $this->originalPrice = AFAPricing::where('package_id', $this->afaPackage->id)
            ->where('role_id', $this->agent->userRole())
            ->first();

        $this->afa_price = $pricing->price ?? $this->afaPackage->price;
        $this->afa_cost = $this->afaPackage->cost;
        $this->afa_profit = $this->afa_price - $this->originalPrice->price;

        //check if the package price is higher than the agent price
        if ($this->originalPrice->price > $this->afa_price) {
            toastr('AFA price is lower than the original price. Please contact the business owner directly.', 'error');
            return;
        }
    }

    private function isValidPhoneNumber($phoneNumber)
    {
        $isValid = true;
        (new GhanaPhoneNumber())->validate('phone', $phoneNumber, function ($message) use (&$isValid) {
            $isValid = false;
        });
        return $isValid;
    }

    public function initiatePayment()
    {
        // Ensure services are available
        $this->initializeServices();

        $this->validate([
            'fullname' => 'required|string|min:3',
            'phone' => 'required|string|regex:/^[0-9]{10}$/',
            'ghana_card' => 'required|string|min:15',
            'occupation' => 'required|string',
            'dob' => 'required|date|before:today',
            'paymentNumber' => 'required|digits:10',
            'paymentNetwork' => 'required',
        ]);

        $this->uniqueRef = $this->generateUniqueRef();
        $this->isProcessing = true;

        //check if real pricing is higher than the package price
        if ($this->originalPrice->price > $this->afa_price) {
            toastr('AFA price is lower than the original price. Please contact the business owner directly.', 'error');
            return;
        }

        try {
            if (!$this->isValidPhoneNumber($this->paymentNumber)) {
                toastr()->error('Invalid payment number. Please try again.');
                return;
            }

            $paymentDetails = AFAOrderPayment::where('contact', $this->paymentNumber)->where('status', 'completed')->first();
            if ($paymentDetails) {
                $this->paymentSummary = [
                    'amount' => $this->afa_price,
                    'payment_number' => $this->paymentNumber,
                    'channel' => $this->paymentNetwork,
                ];
                $this->currentStep = 3;
                return;
            }

            $this->paymentSummary = [
                'amount' => $this->afa_price,
                'payment_number' => $this->paymentNumber,
                'channel' => $this->paymentNetwork,
            ];

            match ($this->paymentProvider->name) {
                'bulkclix' => (function () {
                    $response = $this->bulkClixService->initiatePaymentWithOTP($this->paymentNumber);

                    if ($response) {
                        $this->requestId = $response['data']['otp']['requestId'];
                        $this->ussdCodeForOTP = $response['data']['otp']['ussd_code'];

                        $this->otpSent = true;
                        $this->currentStep = 2;
                    } else {
                        toastr()->error('Failed to initiate BulkClix payment. Please try again.');
                        return;
                    }
                })(),

                default => (function () {
                    $response = $this->moorleService->initiatePayment($this->afa_price, $this->paymentNumber, $this->paymentNetwork, $this->uniqueRef);

                    if ($response) {
                        $this->otpSent = true;
                        $this->currentStep = 2;
                    } else {
                        toastr()->error('Failed to initiate Moorle payment. Please try again.');
                        return;
                    }
                })(),
            };
        } catch (\Exception $e) {
            toastr('An error occurred: ' . $e->getMessage(), 'error');
            $this->addError('payment', 'An error occurred. Please try again.');
        } finally {
            $this->isProcessing = false;
        }
    }

    public function verifyOTP()
    {
        // Ensure services are available
        $this->initializeServices();

        $this->validate([
            'otp' => 'required|digits:6',
        ]);

        $this->isProcessing = true;

        try {
            $response = match ($this->paymentProvider->name) {
                'bulkclix' => $this->bulkClixService->verifyOTP($this->paymentNumber, $this->requestId, $this->otp),
                'moorle' => $this->moorleService->verifyOTP($this->afa_price, $this->paymentNumber, $this->otp, $this->paymentNetwork, $this->uniqueRef),
                default => null,
            };

            if ($response) {
                $this->verificationComplete = true;
                $this->currentStep = 3;
            } else {
                $this->addError('payment', 'Invalid OTP. Please try again.');
            }
        } catch (\Exception $e) {
            $this->addError('payment', 'An error occurred. Please try again.');
        } finally {
            $this->isProcessing = false;
        }
    }

    public function register()
    {
        // Ensure services are available
        $this->initializeServices();

        $this->isProcessing = true;

        try {
            DB::beginTransaction();

            $registration = AFARegistration::create([
                'fullname' => $this->fullname,
                'phone' => $this->phone,
                'ghana_card' => $this->ghana_card,
                'occupation' => $this->occupation,
                'dob' => $this->dob,
                'cost' => $this->afa_cost,
                'price' => $this->originalPrice->price,
                'profit' => $this->originalPrice->price - $this->afa_cost,
                'user_id' => $this->agent->id,
                'status' => 'pending',
                'payment_status' => 'pending',
                'is_customer' => true,
            ]);

            $registration->payment()->create([
                'contact' => $this->paymentNumber,
                'amount' => $this->afa_price,
                'profit' => $this->afa_profit,
                'transaction_id' => $this->uniqueRef,
                'payment_provider_id' => $this->paymentProvider->id,
                'status' => 'pending',
            ]);

            //make api call to send payment prompt
            $response = match ($this->paymentProvider->name) {
                'bulkclix' => $this->bulkClixService->sendPaymentPrompt($this->paymentNumber, $this->afa_price, $this->paymentNetwork, $this->uniqueRef),
                'moorle' => $this->moorleService->sendPaymentPrompt($this->afa_price, $this->paymentNumber, $this->otp, $this->paymentNetwork, $this->uniqueRef),
                default => null,
            };

            if ($response) {
                $this->showPaymentPrompt = true;
                toastr()->success('AFA Registration submitted successfully');
                DB::commit();
            } else {
                $this->addError('payment', 'Payment failed. Please try again.');
                DB::rollBack();
            }
        } catch (\Exception $e) {
            DB::rollBack();
            toastr()->error('An error occurred: ' . $e->getMessage());
            Log::error('Payment failed: ' . $e->getMessage());
            $this->addError('payment', 'An error occurred. Please try again.' . $e->getMessage());
        } finally {
            $this->isProcessing = false;
        }
    }

    public function previousStep()
    {
        $this->currentStep--;
    }

    private function generateUniqueRef()
    {
        $uuid = (string) Str::uuid();
        $prefix = 'AFA-';
        $maxLength = 30;
        $remainingLength = $maxLength - strlen($prefix);
        return $prefix . substr($uuid, 0, $remainingLength);
    }

    public function checkTransactionStatus()
    {
        // Ensure services are available
        $this->initializeServices();

        $isSuccess = match ($this->paymentProvider->name) {
            'bulkclix' => $this->bulkClixService->checkTransactionStatus($this->uniqueRef),
            'moorle' => $this->moorleService->checkTransactionStatus($this->uniqueRef),
            default => null,
        };

        if ($isSuccess) {
            toastr()->success('Transaction successful');

            $afaOrderPayment = AFAOrderPayment::where('transaction_id', $this->uniqueRef)->first();

            if ($afaOrderPayment && $afaOrderPayment->status != 'completed') {
                $afaOrderPayment->update([
                    'status' => 'completed',
                ]);

                $afaOrderPayment->registration()->update([
                    'payment_status' => 'completed',
                ]);
            }
            return redirect()->route('home');
        } else {
            toastr()->error('Transaction failed');
            return redirect()->route('home');
        }
    }
}; ?>

<div class="p-6">
    <!-- Step 1: Registration Details & Payment Info -->
    <div x-show="$wire.currentStep === 1">
        <!-- Registration Form -->
        <div class="space-y-4">
            <div class="bg-gray-50 rounded-lg p-4 mb-6">
                <div class="flex justify-between items-center">
                    <span class="text-gray-600">Registration Fee</span>
                    <span class="font-medium">&#8373; {{ number_format($afa_price, 2) }}</span>
                </div>
            </div>

            <x-input wire:model="fullname" label="Full Name" placeholder="Enter your full name" name="fullname"
                type="text" />
            <x-input wire:model="phone" label="Phone Number" type="tel" maxlength="10"
                placeholder="Enter your phone number" name="phone" />
            <x-input wire:model="ghana_card" label="Ghana Card Number" placeholder="Enter your Ghana card number"
                name="ghana_card" type="text" />
            <x-input wire:model="occupation" label="Occupation" placeholder="Enter your occupation" type="text"
                name="occupation" />
            <x-input wire:model="dob" label="Date of Birth" type="date" name="dob" />

            <!-- Payment Details -->
            <x-select wire:model="paymentNetwork" label="Payment Network" name="paymentNetwork">
                <option value="">Select network</option>
                <option value="MTN">MTN</option>
                <option value="TELECEL">Telecel</option>
                <option value="AIRTELTIGO">AT</option>
            </x-select>

            <x-input wire:model="paymentNumber" label="Payment Number" type="tel" maxlength="10"
                placeholder="Enter payment number" name="paymentNumber" />
        </div>

        <div class="mt-6 flex justify-end space-x-3">
            <button wire:click="$dispatch('close-modal')"
                class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors duration-200">
                Cancel
            </button>
            <x-button wire:click="initiatePayment" wire:loading.attr="disabled">
                <span wire:loading wire:target="initiatePayment">Processing...</span>
                <span wire:loading.remove wire:target="initiatePayment">Continue</span>
            </x-button>
        </div>
    </div>

    <!-- Step 2: OTP Verification -->
    <div x-show="$wire.currentStep === 2">
        <div class="space-y-4 sm:space-y-6">
            <div class="p-4 sm:p-6 bg-gray-50 rounded-lg text-center">
                <i class="ri-message-2-line text-3xl sm:text-4xl text-primary mb-3 sm:mb-4"></i>
                <p class="text-sm sm:text-base text-gray-600">
                    Enter the 6-digit code sent to <span class="font-bold">{{ $paymentNumber }}</span>
                </p>
            </div>

            <!-- USSD Code Display for OTP (with different style) -->
            @if ($ussdCodeForOTP)
                <div
                    class="flex flex-col items-center bg-gradient-to-r from-blue-100 to-blue-50 border-l-4 border-blue-400 rounded-md py-4 px-3 mb-2 shadow-sm">
                    <div class="flex items-center mb-2">
                        <span class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-200 mr-2">
                            <i class="ri-phone-fill text-blue-700 text-xl"></i>
                        </span>
                        <span class="text-base font-semibold text-blue-800">Get OTP via USSD</span>
                    </div>
                    <p class="text-xs text-blue-700 mb-2 text-center">
                        Didn't get the SMS? Dial this code to receive your OTP instantly:
                    </p>
                    <div class="flex items-center justify-center">
                        <span
                            class="bg-blue-50 border border-blue-300 px-4 py-2 rounded-lg font-mono text-lg text-blue-900 tracking-widest shadow-inner">
                            {{ $ussdCodeForOTP }}
                        </span>
                    </div>
                    <div class="mt-2 text-xs text-blue-600 flex items-center justify-center">
                        <i class="ri-information-line mr-1"></i>
                        Use this code on your phone to get the OTP
                    </div>
                </div>
            @endif

            <div class="mb-4 sm:mb-6">
                <input type="text" wire:model="otp"
                    class="shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 text-center text-xl sm:text-2xl tracking-wider leading-tight focus:outline-none focus:shadow-outline"
                    placeholder="Enter 6-digit code" maxlength="6">
                @error('otp')
                    <span class="text-red-500 text-xs sm:text-sm">{{ $message }}</span>
                @enderror
            </div>

            <div class="flex gap-3 sm:gap-4">
                <button wire:click="previousStep" type="button"
                    class="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-700 font-bold py-2 sm:py-3 px-3 sm:px-4 rounded focus:outline-none focus:shadow-outline transition duration-300">
                    <i class="ri-arrow-left-line mr-2"></i>
                    Back
                </button>
                <button wire:click="verifyOTP" wire:loading.attr="disabled" wire:target="verifyOTP"
                    class="flex-1 bg-primary hover:bg-primary-dark text-white font-bold py-2 sm:py-3 px-3 sm:px-4 rounded focus:outline-none focus:shadow-outline transition duration-300">
                    <span wire:loading.remove wire:target="verifyOTP">
                        <i class="ri-shield-check-line mr-2"></i>
                        Verify OTP
                    </span>
                    <span wire:loading wire:target="verifyOTP" class="flex items-center justify-center">
                        <i class="ri-loader-4-line animate-spin mr-2"></i>
                        Verifying...
                    </span>
                </button>
            </div>
        </div>
    </div>

    <!-- Step 3: Registration Summary -->
    <div x-show="$wire.currentStep === 3">
        <h3 class="text-lg font-semibold mb-4">Registration Summary</h3>

        <div class="space-y-4">
            <div class="bg-gray-50 rounded-lg p-4 space-y-3">
                <div class="flex justify-between">
                    <span class="text-gray-600">Full Name</span>
                    <span class="font-medium">{{ $fullname }}</span>
                </div>
                <div class="flex justify-between">
                    <span class="text-gray-600">Phone Number</span>
                    <span class="font-medium">{{ $phone }}</span>
                </div>
                <div class="flex justify-between">
                    <span class="text-gray-600">Amount</span>
                    <span class="font-medium">&#8373; {{ number_format($afa_price, 2) }}</span>
                </div>
                <div class="flex justify-between">
                    <span class="text-gray-600">Payment Number</span>
                    <span class="font-medium">{{ $paymentNumber }}</span>
                </div>
            </div>

            @if (!$showPaymentPrompt)
                <div class="flex justify-between mt-6">
                    <x-button wire:click="previousStep" variant="secondary">
                        Back
                    </x-button>
                    <x-button wire:click="register" wire:loading.attr="disabled">
                        <span wire:loading wire:target="register">Processing...</span>
                        <span wire:loading.remove wire:target="register">Confirm Registration</span>
                    </x-button>
                </div>
            @endif
        </div>
    </div>

    @if ($showPaymentPrompt)
        <div class="w-full p-4 mt-4 text-center rounded-lg bg-yellow-50">
            <p class="font-medium text-yellow-800">
                Please approve the payment request sent to {{ $paymentNumber }}
            </p>
            <p class="mt-1 text-sm text-yellow-600">
                Check your phone for the payment prompt
            </p>
            <div class="mt-4 sm:mt-6">
                <button wire:click="checkTransactionStatus" wire:loading.attr="disabled"
                    wire:target="checkTransactionStatus"
                    class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 sm:py-3 px-4 sm:px-6 rounded-lg transition duration-300">
                    <span wire:loading.remove wire:target="checkTransactionStatus">
                        Check Transaction Status
                    </span>
                    <span wire:loading wire:target="checkTransactionStatus" class="flex items-center justify-center">
                        <i class="ri-loader-4-line animate-spin mr-2"></i>
                        Checking...
                    </span>
                </button>
            </div>
            <x-button wire:click="$dispatch('close-modal')" class="mt-4">
                Close
            </x-button>
        </div>
    @endif

    @error('payment')
        <div class="mt-2 text-sm text-red-500">{{ $message }}</div>
    @enderror
</div>
