<?php

namespace App\Livewire\Forms;

use App\Models\Module;
use App\Models\Package;
use Livewire\Component;
use App\Enums\PackageType;
use App\Models\GlobalCurrency;
use Illuminate\Validation\Rule;
use App\Models\SuperadminPaymentGateway;
use Jantinnerezo\LivewireAlert\LivewireAlert;

class EditPackage extends Component
{

    use LivewireAlert;

    public $package;
    public $packageName;
    public $packagePrice;
    public $description;
    public $currencyID;
    public $price;
    public bool $monthlyStatus;
    public bool $annualStatus;
    public $annualPrice;
    public $monthlyPrice;
    public $sortOrder;
    public bool $isPrivate;
    public bool $isFree;
    public bool $isRecommended;
    public $packageType;
    public $trialStatus;
    public $trialNotificationBeforeDays;
    public $trialMessage;
    public $trialDays;
    public $packageModules = [];
    public $maxOrder;
    public $packageTypes;
    public $modules;
    public $currencies;
    public $showPackageDetailsForm = true;
    public $showModulesForm = false;
    public bool $toggleSelectedModules = false;
    public $selectedModules = [];
    public $currencySymbol;
    public $additionalFeatures;
    public $selectedFeatures = [];
    public $paymentKey;
    public $stripeAnnualPlanId;
    public $stripeMonthlyPlanId;
    public $razorpayAnnualPlanId;
    public $razorpayMonthlyPlanId;
    public $stripeLifetimePlanId;
    public $razorpayLifetimePlanId;
    public $packageCurrency;
    public $branchLimit;
    public $multiposLimit;
    public $flutterwaveAnnualPlanId;
    public $flutterwaveMonthlyPlanId;
    public $paystackAnnualPlanId;
    public $paystackMonthlyPlanId;
    public $paystackLifetimePlanId;
    public $menuItemsLimit;
    public $orderLimit;
    public $staffLimit;
    public $paddleAnnualPriceId;
    public $paddleMonthlyPriceId;
    public $paddleLifetimePriceId;
    public $smsCount; // Add SMS count field
    public bool $carryForwardSms = false; // Add carry forward SMS field
    public $hasSubscribers = false;
    public $canEditCurrency = true;
    public $aiMonthlyTokenLimit = -1;

    public function mount()
    {
        $this->checkPackageSubscriptions();
        $this->initializePackageData();
        $this->initializeFormData();
    }

    private function initializePackageData()
    {
        $this->packageName = $this->package->package_name;
        $this->packagePrice = $this->package->price;
        $this->monthlyStatus = $this->package->monthly_status;
        $this->annualStatus = $this->package->annual_status;
        $this->annualPrice = $this->package->annual_price;
        $this->monthlyPrice = $this->package->monthly_price;
        $this->price = $this->package->price;
        $this->sortOrder = $this->package->sort_order;
        $this->isPrivate = $this->package->is_private;
        $this->isFree = $this->package->is_free;
        $this->isRecommended = $this->package->is_recommended;
        $this->packageType = $this->package->package_type;
        $this->trialStatus = $this->package->trial_status;
        $this->trialNotificationBeforeDays = $this->package->trial_notification_before_days;
        $this->trialMessage = $this->package->trial_message;
        $this->trialDays = $this->package->trial_days;
        $this->packageModules = $this->package->modules->pluck('id')->toArray();
        $this->currencyID = $this->package->currency_id;
        $this->description = $this->package->description;
        $this->stripeAnnualPlanId = $this->package->stripe_annual_plan_id;
        $this->stripeMonthlyPlanId = $this->package->stripe_monthly_plan_id;
        $this->razorpayAnnualPlanId = $this->package->razorpay_annual_plan_id;
        $this->razorpayMonthlyPlanId = $this->package->razorpay_monthly_plan_id;
        $this->flutterwaveAnnualPlanId = $this->package->flutterwave_annual_plan_id;
        $this->flutterwaveMonthlyPlanId = $this->package->flutterwave_monthly_plan_id;
        $this->paystackAnnualPlanId = $this->package->paystack_annual_plan_id;
        $this->paystackMonthlyPlanId = $this->package->paystack_monthly_plan_id;
        $this->paddleAnnualPriceId = $this->package->paddle_annual_price_id;
        $this->paddleMonthlyPriceId = $this->package->paddle_monthly_price_id;
        $this->paddleLifetimePriceId = $this->package->paddle_lifetime_price_id;
        $this->selectedFeatures = $this->package->additional_features ? json_decode($this->package->additional_features, true) : [];
        $this->branchLimit = $this->package->branch_limit;
        $this->multiposLimit = $this->package->multipos_limit ?? -1;
        $this->menuItemsLimit = $this->package->menu_items_limit ?? -1;
        $this->orderLimit = $this->package->order_limit ?? -1;
        $this->staffLimit = $this->package->staff_limit ?? -1;
        $this->smsCount = $this->package->sms_count; // Initialize SMS count
        $this->carryForwardSms = $this->package->carry_forward_sms ?? false; // Initialize carry forward SMS
        $this->aiMonthlyTokenLimit = $this->package->ai_monthly_token_limit ?? -1;
    }

    private function initializeFormData()
    {
        $this->selectedModules = $this->packageModules;
        $this->currencySymbol = GlobalCurrency::find($this->currencyID)->currency_symbol ?? null;
        $this->maxOrder = Package::count();
        $this->packageTypes = array_filter(
            PackageType::cases(),
            fn($type) => !in_array($type, [PackageType::TRIAL, PackageType::DEFAULT, PackageType::FREE])
        );
        $this->modules = $this->getAvailableModules();
        $this->currencies = GlobalCurrency::all();
        $this->toggleSelectedModules = count($this->selectedModules) === $this->modules->count();
        $this->additionalFeatures = Package::ADDITIONAL_FEATURES;
        $this->paymentKey = SuperadminPaymentGateway::first();
    }

    /**
     * Get available modules, filtering out disabled modules
     */
    private function getAvailableModules()
    {
        return Module::adminModules()->get()
            ->filter(fn ($module) => $module->name !== 'Sms' || module_enabled('Sms'));
    }

    private function checkPackageSubscriptions()
    {
        // Check if any restaurants have subscribed to this package
        $this->hasSubscribers = $this->package->restaurants()->exists();
        $this->canEditCurrency = !$this->hasSubscribers;
    }

    public function updatedCurrencyID()
    {
        $this->currencySymbol = GlobalCurrency::find($this->currencyID)->currency_symbol ?? null;
    }

    public function updatedPackageType($value)
    {
        if ($value == PackageType::LIFETIME) {
            $this->annualStatus = false;
            $this->monthlyStatus = false;
            $this->annualPrice = null;
            $this->monthlyPrice = null;
        }
    }

    public function updatedIsFree($value)
    {
        $this->packageType = $value ? PackageType::FREE : $this->package->package_type;

        if ($value) {
            $this->annualStatus = false;
            $this->monthlyStatus = false;
            $this->annualPrice = null;
            $this->monthlyPrice = null;
        }
    }

    public function updatedToggleSelectedModules($value)
    {
        $this->selectedModules = $value ? $this->modules->pluck('id')->toArray() : [];
        $this->currencies = GlobalCurrency::get();
        $this->packageCurrency = $this->package->currency_id;
    }

    public function submitForm()
    {
        abort_if((!user_can('Update Package')), 403);

        $validateRules = [
            'packageName' => [
                'required',
                'string',
                'max:255',
                Rule::unique('packages', 'package_name')->ignore($this->package->id),
            ],
            'isFree' => 'required|boolean',
            'sortOrder' => 'nullable|integer|required_if:packageType,!trial',
            'isPrivate' => 'required|boolean',
            'isRecommended' => 'required|boolean',
            'packageType' => 'required_if:isFree,false',
            'currencyID' => [
                'required_if:isFree,false',
                function ($attribute, $value, $fail) {
                    // Prevent currency change if package has subscribers
                    if (!$this->canEditCurrency && $value != $this->package->currency_id) {
                        $fail('Currency cannot be changed because restaurants have already subscribed to this package.');
                    }
                },
            ],
            'annualStatus' => 'required_if:packageType,standard|boolean',
            'monthlyStatus' => 'required_if:packageType,standard|boolean',
            'price' => 'required_if:packageType,lifetime|numeric|nullable',
            'annualPrice' => [
                'nullable',
                'numeric',
                'required_if:annualStatus,true',
            ],
            'monthlyPrice' => [
                'nullable',
                'numeric',
                'required_if:monthlyStatus,true',
            ],
            'trialStatus' => 'required_if:packageType,trial|boolean|nullable',
            'trialNotificationBeforeDays' => 'required_if:packageType,trial|integer|nullable',
            'trialMessage' => 'required_if:packageType,trial|string|nullable',
            'trialDays' => 'required_if:packageType,trial|integer|nullable',
            'description' => 'required',
            'selectedModules' => 'array|min:1',
            'branchLimit' => [
                'nullable',
                'integer',
                'min:-1',
                Rule::requiredIf(fn() => in_array('Change Branch', $this->selectedFeatures))
            ],
            'multiposLimit' => [
                'nullable',
                'integer',
                'min:-1',
                Rule::requiredIf(fn() => $this->isMultiPOSModuleSelected())
            ],
            'menuItemsLimit' => [
                Rule::requiredIf(fn() => $this->isMenuItemModuleSelected()),
                'nullable',
                'integer',
                'min:-1',
            ],
            'orderLimit' => [
                Rule::requiredIf(fn() => $this->isOrderModuleSelected()),
                'nullable',
                'integer',
                'min:-1',
            ],
            'staffLimit' => [
                Rule::requiredIf(fn() => $this->isStaffModuleSelected()),
                'nullable',
                'integer',
                'min:-1',
            ],
            'smsCount' => [
                Rule::requiredIf(fn() => $this->isSmsModuleSelected()),
                'nullable',
                'integer',
                'min:-1',
            ],
            'carryForwardSms' => 'boolean',
            'aiMonthlyTokenLimit' => [
                Rule::requiredIf(fn() => $this->isAitoolsModuleSelected()),
                'nullable',
                'integer',
                'min:-1',
            ],
        ];

        if ($this->paymentKey->razorpay_status == 1) {
            $validateRules['razorpayMonthlyPlanId'] = $this->monthlyStatus ? 'required' : 'nullable';
            $validateRules['razorpayAnnualPlanId'] = $this->annualStatus ? 'required' : 'nullable';
        }

        if ($this->paymentKey->stripe_status == 1) {
            $validateRules['stripeMonthlyPlanId'] = $this->monthlyStatus ? 'required' : 'nullable';
            $validateRules['stripeAnnualPlanId'] = $this->annualStatus ? 'required' : 'nullable';
        }

        if ($this->paymentKey->flutterwave_status == 1) {
            $validateRules['flutterwaveMonthlyPlanId'] = $this->monthlyPrice ? 'required' : 'nullable';
            $validateRules['flutterwaveAnnualPlanId'] = $this->annualPrice ? 'required' : 'nullable';
        }

        if ($this->paymentKey->paystack_status == 1) {
            $validateRules['paystackMonthlyPlanId'] = $this->monthlyPrice ? 'required' : 'nullable';
            $validateRules['paystackAnnualPlanId'] = $this->annualPrice ? 'required' : 'nullable';
        }

        if ($this->paymentKey->paddle_status == 1) {
            $validateRules['paddleMonthlyPriceId'] = $this->monthlyPrice ? 'required' : 'nullable';
            $validateRules['paddleAnnualPriceId'] = $this->annualPrice ? 'required' : 'nullable';
            $validateRules['paddleLifetimePriceId'] = ($this->packageType === 'lifetime') ? 'required' : 'nullable';
        }

        $validateMessages = [
            'packageName.unique' => 'The package name has already been taken.',
            'price.required_if' => 'The price field is required.',
            'annualPrice.required_if' => 'The annual price field is required.',
            'monthlyPrice.required_if' => 'The monthly price field is required.',
            'trialStatus.required_if' => 'The trial status field is required.',
            'trialNotificationBeforeDays.required_if' => 'The trial notification before days field is required.',
            'trialMessage.required_if' => 'The trial message field is required.',
            'trialDays.required_if' => 'The trial days field is required.',
            'selectedModules.min' => 'Please select at least one module',
            'branchLimit.required_if' => 'The branch limit field is required when Change Branch is selected.',
            'menuItemsLimit.required_if' => 'Menu items limit is required when Menu Item module is selected.',
            'menuItemsLimit.min' => 'Menu items limit must be -1 or greater.',
            'orderLimit.required_if' => 'Order limit is required when Order module is selected.',
            'orderLimit.min' => 'Order limit must be -1 or greater.',
            'staffLimit.required_if' => 'Staff limit is required when Staff module is selected.',
            'staffLimit.min' => 'Staff limit must be -1 or greater.',
            'smsCount.required_if' => 'SMS count is required when SMS module is enabled.',
            'smsCount.min' => 'SMS count must be at least -1 (use -1 for unlimited).',
            'aiMonthlyTokenLimit.required_if' => 'AI monthly token limit is required when Aitools module is enabled.',
            'aiMonthlyTokenLimit.min' => 'AI monthly token limit must be at least -1 (use -1 for unlimited).',
        ];

        $this->validate($validateRules, $validateMessages);

        if ($this->package->sort_order != $this->sortOrder) {
            Package::where('sort_order', '>=', $this->sortOrder)
                ->where('id', '!=', $this->package->id)
                ->increment('sort_order');
        }

        $this->package->update([
            'package_name' => $this->packageName,
            'description' => $this->description,
            'package_type' => $this->packageType,
            'price' => $this->packageType === PackageType::LIFETIME ? $this->price : 0,
            'currency_id' => $this->currencyID,
            'annual_price' => $this->annualPrice ?: null,
            'monthly_price' => $this->monthlyPrice ?: null,
            'is_free' => $this->isFree,
            'monthly_status' => $this->monthlyStatus,
            'annual_status' => $this->annualStatus,
            'sort_order' => $this->sortOrder,
            'is_private' => $this->isPrivate,
            'is_recommended' => $this->isRecommended,
            'trial_status' => $this->trialStatus,
            'trial_notification_before_days' => $this->trialNotificationBeforeDays,
            'trial_message' => $this->trialMessage,
            'trial_days' => $this->trialDays,
            'stripe_annual_plan_id' => $this->stripeAnnualPlanId,
            'stripe_monthly_plan_id' => $this->stripeMonthlyPlanId,
            'razorpay_annual_plan_id' => $this->razorpayAnnualPlanId,
            'razorpay_monthly_plan_id' => $this->razorpayMonthlyPlanId,
            'stripe_lifetime_plan_id' => $this->packageType === PackageType::LIFETIME ? $this->stripeLifetimePlanId : null,
            'razorpay_lifetime_plan_id' => $this->packageType === PackageType::LIFETIME ? $this->razorpayLifetimePlanId : null,
            'flutterwave_annual_plan_id' => $this->flutterwaveAnnualPlanId,
            'flutterwave_monthly_plan_id' => $this->flutterwaveMonthlyPlanId,
            'paystack_annual_plan_id' => $this->paystackAnnualPlanId,
            'paystack_monthly_plan_id' => $this->paystackMonthlyPlanId,
            'paystack_lifetime_plan_id' => $this->packageType === PackageType::LIFETIME ? $this->paystackLifetimePlanId : null,
            'paddle_annual_price_id' => $this->paddleAnnualPriceId,
            'paddle_monthly_price_id' => $this->paddleMonthlyPriceId,
            'paddle_lifetime_price_id' => $this->packageType === PackageType::LIFETIME ? $this->paddleLifetimePriceId : null,
            'additional_features' => json_encode($this->selectedFeatures),
            'branch_limit' => $this->branchLimit,
            'multipos_limit' => $this->multiposLimit,
            'menu_items_limit' => $this->menuItemsLimit,
            'order_limit' => $this->orderLimit,
            'staff_limit' => $this->staffLimit,
            'sms_count' => $this->smsCount ?? -1, // Ensure we always save a valid integer
            'carry_forward_sms' => $this->carryForwardSms,
            'ai_monthly_token_limit' => $this->aiMonthlyTokenLimit ?? -1,
        ]);

        $this->package->modules()->sync($this->selectedModules);

        $this->package->restaurants->each(function ($restaurant) {
            clearRestaurantModulesCache($restaurant->id);
            cache()->forget('restaurant_' . $restaurant->id . '_staff_stats');
            cache()->forget('restaurant_' . $restaurant->id . '_menu_item_stats');
            // Clear order stats cache for all branches of this restaurant
            $restaurant->branches->each(function ($branch) {
                cache()->forget('branch_' . $branch->id . '_order_stats');
            });
        });


        $this->dispatch('hideEditPackage');

        $this->reset('package');

        $this->alert('success', __('messages.packageUpdated'), [
            'toast' => true,
            'position' => 'top-end',
            'showCancelButton' => false,
            'cancelButtonText' => __('app.close')
        ]);

        return $this->redirect(route('superadmin.packages.index'), navigate: true);
    }

    public function render()
    {
        return view('livewire.forms.edit-package');
    }

    public function isSmsModuleSelected()
    {
        $smsModule = Module::adminModules()->where('name', 'Sms')->first();
        return $smsModule && in_array($smsModule->id, $this->selectedModules);
    }

    public function isMultiPOSModuleSelected()
    {
        $multiposModule = Module::adminModules()->where('name', 'MultiPOS')->first();
        return $multiposModule && in_array($multiposModule->id, $this->selectedModules);
    }

    public function isMenuItemModuleSelected()
    {
        $menuItemModule = Module::adminModules()->where('name', 'Menu Item')->first();
        return $menuItemModule && in_array($menuItemModule->id, $this->selectedModules);
    }

    public function isOrderModuleSelected()
    {
        $orderModule = Module::adminModules()->where('name', 'Order')->first();
        return $orderModule && in_array($orderModule->id, $this->selectedModules);
    }

    public function isStaffModuleSelected()
    {
        $staffModule = Module::adminModules()->where('name', 'Staff')->first();
        return $staffModule && in_array($staffModule->id, $this->selectedModules);
    }

    public function isAitoolsModuleSelected()
    {
        $aitoolsModule = Module::where('name', 'Aitools')->first();
        return $aitoolsModule && in_array($aitoolsModule->id, $this->selectedModules);
    }

    public function updatedSelectedModules()
    {
        // Reset SMS count to default when SMS module is deselected
        if (!$this->isSmsModuleSelected()) {
            $this->smsCount = -1; // Default to -1 (unlimited)
            $this->carryForwardSms = false; // Reset carry forward SMS
        }

        // Reset menu items limit when Menu Item module is deselected
        if (!$this->isMenuItemModuleSelected()) {
            $this->menuItemsLimit = -1;
        }

        // Reset order limit when Order module is deselected
        if (!$this->isOrderModuleSelected()) {
            $this->orderLimit = -1;
        }

        // Reset staff limit when Staff module is deselected
        if (!$this->isStaffModuleSelected()) {
            $this->staffLimit = -1;
        }

         // Reset AI monthly token limit when Aitools module is deselected
        if (!$this->isAitoolsModuleSelected()) {
            $this->aiMonthlyTokenLimit = -1;
        }

    }

}
