<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Models\Company;
use App\Models\CompanyFinancialSettings;
use App\Models\Plan;
use App\Models\SubscriptionRequest;
use Filament\Actions\Action;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Exceptions\Halt;
use Illuminate\Support\Facades\Auth;

/**
 * Company Settings Page.
 *
 * Allows Company Admins to configure their company's settings,
 * view subscription info, and request changes.
 *
 * TABS:
 * 1. Empresa - Branding, contact info, localization
 * 2. Operación - Credit parameters, simplified input
 * 3. Suscripción - Plan info, usage, request changes (read-only + actions)
 */
class CompanySettings extends Page implements HasForms
{
    use InteractsWithForms;

    protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-cog-6-tooth';

    protected static ?string $navigationLabel = 'Configuración';

    protected static ?string $title = 'Configuración de la Compañía';

    protected static ?string $slug = 'company-settings';

    protected static ?int $navigationSort = 99;

    protected string $view = 'filament.pages.company-settings';

    // Form data
    public ?array $companyData = [];

    public ?array $operationalData = [];

    // Active tab
    public string $activeTab = 'empresa';

    public function mount(): void
    {
        $this->authorizeAccess();

        $company = $this->getCompany();
        $settings = $this->getFinancialSettings();

        // Load company data
        $this->companyData = [
            'name' => $company->name,
            'business_name' => $company->business_name,
            'tax_id' => $company->tax_id,
            'legal_representative' => $company->legal_representative,
            'email' => $company->email,
            'phone' => $company->phone,
            'address' => $company->address,
            'logo_path' => $company->logo_path,
            'primary_color' => $company->primary_color,
            'secondary_color' => $company->secondary_color,
            'timezone' => $company->timezone,
            'date_format' => $company->date_format,
            'locale' => $company->locale,
        ];

        // Load operational data
        $this->operationalData = [
            'min_credit_amount' => $settings->min_credit_amount,
            'max_credit_amount' => $settings->max_credit_amount,
            'default_credit_amount' => $settings->default_credit_amount,
            'min_interest_rate' => $settings->min_interest_rate,
            'max_interest_rate' => $settings->max_interest_rate,
            'default_interest_rate' => $settings->default_interest_rate,
            'min_installments' => $settings->min_installments,
            'max_installments' => $settings->max_installments,
            'default_installments' => $settings->default_installments,
            'allowed_periodicities' => $settings->allowed_periodicities ?? ['daily', 'weekly', 'biweekly', 'monthly'],
            'default_periodicity' => $settings->default_periodicity,
            'default_grace_days' => $settings->default_grace_days,
            'days_until_delayed' => $settings->days_until_delayed,
            'allow_partial_payments' => $settings->allow_partial_payments,
            'simplified_input_enabled' => $settings->simplified_input_enabled,
            'simplified_input_multiplier' => $settings->simplified_input_multiplier,
            'simplified_input_require_confirm' => $settings->simplified_input_require_confirm,
        ];

        $this->companyForm->fill($this->companyData);
        $this->operationalForm->fill($this->operationalData);
    }

    protected function authorizeAccess(): void
    {
        $user = Auth::user();

        // Must be logged in with a company
        if (! $user || ! $user->company_id) {
            abort(403, 'No tiene acceso a esta página.');
        }

        // Must be admin or super_admin
        if (! $user->hasAnyRole(['super_admin', 'admin'])) {
            abort(403, 'Solo los administradores pueden acceder a la configuración.');
        }
    }

    public static function canAccess(): bool
    {
        $user = Auth::user();

        return $user
            && $user->company_id
            && $user->hasAnyRole(['super_admin', 'admin']);
    }

    protected function getCompany(): Company
    {
        return Company::findOrFail(Auth::user()->company_id);
    }

    protected function getFinancialSettings(): CompanyFinancialSettings
    {
        return CompanyFinancialSettings::forCompany(Auth::user()->company_id);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // FORMS
    // ═══════════════════════════════════════════════════════════════════════════

    protected function getForms(): array
    {
        return [
            'companyForm',
            'operationalForm',
        ];
    }

    public function companyForm(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make('Información de la Empresa')
                    ->description('Datos básicos de tu empresa')
                    ->schema([
                        Grid::make(2)->schema([
                            TextInput::make('name')
                                ->label('Nombre de la Empresa')
                                ->required()
                                ->maxLength(255),

                            TextInput::make('business_name')
                                ->label('Nombre Comercial')
                                ->helperText('Nombre para documentos y reportes')
                                ->maxLength(255),

                            TextInput::make('tax_id')
                                ->label('NIT / RUC')
                                ->maxLength(50),

                            TextInput::make('legal_representative')
                                ->label('Representante Legal')
                                ->maxLength(255),

                            TextInput::make('email')
                                ->label('Email de Contacto')
                                ->email()
                                ->required(),

                            TextInput::make('phone')
                                ->label('Teléfono')
                                ->tel(),

                            Textarea::make('address')
                                ->label('Dirección')
                                ->rows(2)
                                ->columnSpanFull(),
                        ]),
                    ]),

                Section::make('Marca e Identidad')
                    ->description('Logo y colores de tu empresa')
                    ->collapsed()
                    ->schema([
                        Grid::make(2)->schema([
                            FileUpload::make('logo_path')
                                ->label('Logo')
                                ->image()
                                ->directory('company-logos')
                                ->maxSize(2048)
                                ->helperText('Máximo 2MB. Formatos: PNG, JPG, SVG'),

                            Grid::make(1)->schema([
                                ColorPicker::make('primary_color')
                                    ->label('Color Primario'),

                                ColorPicker::make('secondary_color')
                                    ->label('Color Secundario'),
                            ]),
                        ]),
                    ]),

                Section::make('Localización')
                    ->description('Configuración regional')
                    ->collapsed()
                    ->schema([
                        Grid::make(3)->schema([
                            Select::make('timezone')
                                ->label('Zona Horaria')
                                ->options([
                                    'America/Bogota' => 'Colombia (Bogotá)',
                                    'America/Lima' => 'Perú (Lima)',
                                    'America/Mexico_City' => 'México (Ciudad de México)',
                                    'America/Guayaquil' => 'Ecuador (Guayaquil)',
                                    'America/La_Paz' => 'Bolivia (La Paz)',
                                    'America/Caracas' => 'Venezuela (Caracas)',
                                    'America/Panama' => 'Panamá',
                                    'America/Santiago' => 'Chile (Santiago)',
                                    'America/Argentina/Buenos_Aires' => 'Argentina (Buenos Aires)',
                                ])
                                ->searchable(),

                            Select::make('date_format')
                                ->label('Formato de Fecha')
                                ->options([
                                    'd/m/Y' => 'DD/MM/AAAA (31/12/2026)',
                                    'm/d/Y' => 'MM/DD/AAAA (12/31/2026)',
                                    'Y-m-d' => 'AAAA-MM-DD (2026-12-31)',
                                    'd-m-Y' => 'DD-MM-AAAA (31-12-2026)',
                                ]),

                            Select::make('locale')
                                ->label('Idioma/Región')
                                ->options([
                                    'es_CO' => 'Español (Colombia)',
                                    'es_MX' => 'Español (México)',
                                    'es_PE' => 'Español (Perú)',
                                    'es_EC' => 'Español (Ecuador)',
                                    'es_AR' => 'Español (Argentina)',
                                    'en_US' => 'English (US)',
                                ]),
                        ]),
                    ]),
            ])
            ->statePath('companyData');
    }

    public function operationalForm(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make('Parámetros de Crédito')
                    ->description('Límites y valores por defecto para nuevos créditos')
                    ->schema([
                        Grid::make(3)->schema([
                            TextInput::make('min_credit_amount')
                                ->label('Monto Mínimo')
                                ->numeric()
                                ->prefix('$')
                                ->required(),

                            TextInput::make('max_credit_amount')
                                ->label('Monto Máximo')
                                ->numeric()
                                ->prefix('$')
                                ->required(),

                            TextInput::make('default_credit_amount')
                                ->label('Monto por Defecto')
                                ->numeric()
                                ->prefix('$')
                                ->helperText('Valor pre-llenado en formularios'),
                        ]),

                        Grid::make(3)->schema([
                            TextInput::make('min_interest_rate')
                                ->label('Tasa Mínima')
                                ->numeric()
                                ->suffix('%')
                                ->minValue(0)
                                ->maxValue(100),

                            TextInput::make('max_interest_rate')
                                ->label('Tasa Máxima')
                                ->numeric()
                                ->suffix('%')
                                ->minValue(0)
                                ->maxValue(100),

                            TextInput::make('default_interest_rate')
                                ->label('Tasa por Defecto')
                                ->numeric()
                                ->suffix('%'),
                        ]),

                        Grid::make(3)->schema([
                            TextInput::make('min_installments')
                                ->label('Cuotas Mínimas')
                                ->numeric()
                                ->minValue(1)
                                ->required(),

                            TextInput::make('max_installments')
                                ->label('Cuotas Máximas')
                                ->numeric()
                                ->minValue(1)
                                ->required(),

                            TextInput::make('default_installments')
                                ->label('Cuotas por Defecto')
                                ->numeric(),
                        ]),
                    ]),

                Section::make('Periodicidad y Pagos')
                    ->description('Configuración de periodicidad y comportamiento de pagos')
                    ->collapsed()
                    ->schema([
                        Grid::make(2)->schema([
                            Select::make('allowed_periodicities')
                                ->label('Periodicidades Permitidas')
                                ->multiple()
                                ->options([
                                    'daily' => 'Diaria',
                                    'weekly' => 'Semanal',
                                    'biweekly' => 'Quincenal',
                                    'monthly' => 'Mensual',
                                ])
                                ->required(),

                            Select::make('default_periodicity')
                                ->label('Periodicidad por Defecto')
                                ->options([
                                    'daily' => 'Diaria',
                                    'weekly' => 'Semanal',
                                    'biweekly' => 'Quincenal',
                                    'monthly' => 'Mensual',
                                ])
                                ->required(),
                        ]),

                        Grid::make(2)->schema([
                            TextInput::make('default_grace_days')
                                ->label('Días de Gracia por Defecto')
                                ->numeric()
                                ->minValue(0)
                                ->maxValue(30)
                                ->helperText('Días antes de aplicar mora'),

                            TextInput::make('days_until_delayed')
                                ->label('Días para Marcar como Moroso')
                                ->numeric()
                                ->minValue(1)
                                ->helperText('Días después del vencimiento'),
                        ]),

                        Toggle::make('allow_partial_payments')
                            ->label('Permitir Pagos Parciales')
                            ->helperText('Permitir pagos menores al valor de la cuota'),
                    ]),

                Section::make('Entrada Simplificada (PWA)')
                    ->description('Permite a los collectors digitar montos sin los últimos ceros')
                    ->collapsed()
                    ->schema([
                        Toggle::make('simplified_input_enabled')
                            ->label('Activar Modo Simplificado')
                            ->helperText('Los collectors podrán digitar "1500" en lugar de "1,500,000"')
                            ->live(),

                        Grid::make(2)
                            ->schema([
                                Select::make('simplified_input_multiplier')
                                    ->label('Multiplicador')
                                    ->options([
                                        100 => '× 100',
                                        1000 => '× 1,000 (Recomendado)',
                                        10000 => '× 10,000',
                                        1000000 => '× 1,000,000',
                                    ])
                                    ->helperText('El valor digitado se multiplica por este factor'),

                                Toggle::make('simplified_input_require_confirm')
                                    ->label('Requiere Confirmación')
                                    ->helperText('Mostrar checkbox de confirmación del monto real'),
                            ])
                            ->visible(fn ($get) => $get('simplified_input_enabled')),
                    ]),
            ])
            ->statePath('operationalData');
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // ACTIONS
    // ═══════════════════════════════════════════════════════════════════════════

    public function saveCompanySettings(): void
    {
        try {
            $data = $this->companyForm->getState();

            $company = $this->getCompany();
            $company->update($data);

            Notification::make()
                ->title('Configuración guardada')
                ->body('Los datos de la empresa se actualizaron correctamente.')
                ->success()
                ->send();
        } catch (Halt $exception) {
            return;
        }
    }

    public function saveOperationalSettings(): void
    {
        try {
            $data = $this->operationalForm->getState();

            $settings = $this->getFinancialSettings();

            // Set simplified input contexts based on enabled state
            if ($data['simplified_input_enabled']) {
                $data['simplified_input_contexts'] = ['pwa_credit_create', 'pwa_payment_create'];
            } else {
                $data['simplified_input_contexts'] = [];
            }

            $settings->update($data);
            $settings->updated_by_user_id = Auth::id();
            $settings->save();

            Notification::make()
                ->title('Configuración guardada')
                ->body('Los parámetros operativos se actualizaron correctamente.')
                ->success()
                ->send();
        } catch (Halt $exception) {
            return;
        }
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // SUBSCRIPTION DATA
    // ═══════════════════════════════════════════════════════════════════════════

    public function getSubscriptionData(): array
    {
        $company = $this->getCompany();
        $subscription = $company->currentSubscription;
        $plan = $subscription?->plan;

        return [
            'has_subscription' => $subscription !== null,
            'plan' => $plan,
            'subscription' => $subscription,
            'usage' => $company->getUsageStats(),
            'pending_requests' => SubscriptionRequest::where('company_id', $company->id)
                ->pending()
                ->count(),
        ];
    }

    public function getAvailablePlans(): array
    {
        return Plan::active()
            ->public()
            ->ordered()
            ->get()
            ->toArray();
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // HEADER ACTIONS
    // ═══════════════════════════════════════════════════════════════════════════

    protected function getHeaderActions(): array
    {
        return [
            Action::make('request_change')
                ->label('Solicitar Cambio')
                ->icon('heroicon-o-arrow-up-circle')
                ->color('warning')
                ->modalHeading('Solicitar Cambio de Plan o Límites')
                ->modalDescription('Tu solicitud será revisada por el equipo de soporte.')
                ->modalWidth('lg')
                ->form([
                    Select::make('request_type')
                        ->label('Tipo de Solicitud')
                        ->options(SubscriptionRequest::getRequestTypes())
                        ->required()
                        ->live(),

                    Select::make('requested_plan_id')
                        ->label('Plan Solicitado')
                        ->options(fn () => Plan::active()->pluck('name', 'id'))
                        ->visible(fn ($get) => in_array($get('request_type'), ['upgrade_plan', 'downgrade_plan']))
                        ->required(fn ($get) => in_array($get('request_type'), ['upgrade_plan', 'downgrade_plan'])),

                    TextInput::make('requested_value')
                        ->label('Valor Solicitado')
                        ->helperText('Ej: 20 usuarios, 500 créditos, etc.')
                        ->visible(fn ($get) => in_array($get('request_type'), [
                            'increase_users', 'increase_collectors', 'increase_credits',
                            'increase_volume', 'increase_clients',
                        ]))
                        ->required(fn ($get) => in_array($get('request_type'), [
                            'increase_users', 'increase_collectors', 'increase_credits',
                            'increase_volume', 'increase_clients',
                        ])),

                    Textarea::make('comments')
                        ->label('Comentarios / Justificación')
                        ->required()
                        ->rows(4)
                        ->helperText('Explica por qué necesitas este cambio'),
                ])
                ->action(function (array $data): void {
                    $company = $this->getCompany();
                    $subscription = $company->currentSubscription;

                    // Check if can create request
                    if (! SubscriptionRequest::canCreateRequest($company->id)) {
                        Notification::make()
                            ->title('Límite de solicitudes')
                            ->body('Ya tienes solicitudes pendientes. Espera a que sean procesadas.')
                            ->warning()
                            ->send();

                        return;
                    }

                    // Get current value based on request type
                    $currentValue = match ($data['request_type']) {
                        'increase_users' => $subscription?->getMaxUsers() ?? 0,
                        'increase_collectors' => $subscription?->getMaxCollectors() ?? 0,
                        'increase_credits' => $subscription?->getMaxActiveCredits() ?? 0,
                        'increase_volume' => $subscription?->getMaxMonthlyVolume() ?? 0,
                        'increase_clients' => $subscription?->getMaxClients() ?? 0,
                        'upgrade_plan', 'downgrade_plan' => $subscription?->plan?->name ?? 'Sin plan',
                        default => null,
                    };

                    SubscriptionRequest::create([
                        'company_id' => $company->id,
                        'subscription_id' => $subscription?->id,
                        'requested_by_user_id' => Auth::id(),
                        'request_type' => $data['request_type'],
                        'requested_plan_id' => $data['requested_plan_id'] ?? null,
                        'current_value' => is_numeric($currentValue) ? number_format($currentValue) : $currentValue,
                        'requested_value' => $data['requested_value'] ?? null,
                        'comments' => $data['comments'],
                    ]);

                    Notification::make()
                        ->title('Solicitud enviada')
                        ->body('Tu solicitud ha sido enviada y será revisada pronto.')
                        ->success()
                        ->send();
                }),
        ];
    }
}
