<?php

namespace App\Filament\Resources\Clients\Schemas;

use App\Models\Client;
use App\Models\DepartmentMunicipality;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class ClientForm
{
    /**
     * Cache departamentos para evitar queries repetidas en cada repeater item.
     */
    private static ?array $departmentOptions = null;

    private static function getDepartmentOptions(): array
    {
        return self::$departmentOptions ??= DepartmentMunicipality::query()
            ->distinct()
            ->orderBy('department_name')
            ->pluck('department_name', 'department_name')
            ->toArray();
    }

    public static function configure(Schema $schema): Schema
    {
        $user = Auth::user();
        $isSuperAdmin = $user->hasRole('super_admin');

        return $schema
            ->components([

                // ─── Tenant fields ───────────────────────────────
                Hidden::make('company_id')
                    ->default(fn () => Auth::user()->company_id),

                Hidden::make('created_by_user_id')
                    ->default(fn () => Auth::id()),

                // ─── 1. Información General ──────────────────────
                Section::make('Información General')
                    ->icon('heroicon-o-user')
                    ->columns(2)
                    ->schema([
                        Select::make('company_id')
                            ->label('Compañía')
                            ->relationship('company', 'name')
                            ->required()
                            ->hidden(fn () => ! $isSuperAdmin)
                            ->default(fn () => $isSuperAdmin ? null : $user->company_id)
                            ->columnSpanFull(),

                        TextInput::make('name')
                            ->label('Nombre Completo')
                            ->placeholder('Ej: Carlos Andrés Pérez')
                            ->required()
                            ->maxLength(255),

                        TextInput::make('identification')
                            ->label('Identificación (Cédula)')
                            ->numeric()
                            ->required()
                            ->placeholder('Ej: 1032456789')
                            ->unique(
                                Client::class,
                                'identification',
                                ignoreRecord: true,
                                modifyRuleUsing: function ($rule, Get $get) use ($user, $isSuperAdmin) {
                                    $companyId = $isSuperAdmin ? $get('company_id') : $user->company_id;

                                    return $rule->where('company_id', $companyId);
                                },
                            )
                            ->maxLength(255),

                        Toggle::make('is_active')
                            ->label('Cliente Activo')
                            ->default(true)
                            ->columnSpanFull(),
                    ])
                    ->columnSpanFull(),

                // ─── 2. Contacto ─────────────────────────────────
                Section::make('Contacto')
                    ->icon('heroicon-o-phone')
                    ->columns(2)
                    ->schema([
                        TextInput::make('phone')
                            ->label('Teléfono')
                            ->placeholder('3001234567')
                            ->tel()
                            ->nullable(),

                        TextInput::make('email')
                            ->label('Correo Electrónico')
                            ->placeholder('ejemplo@correo.com')
                            ->email()
                            ->nullable(),
                    ])
                    ->columnSpanFull(),

                // ─── 3. Método de Pago ───────────────────────────
                Section::make('Método de Pago')
                    ->icon('heroicon-o-credit-card')
                    ->schema([
                        Select::make('preferred_payment_method')
                            ->label('Método de Pago Preferido')
                            ->options([
                                'physical' => 'Pago Físico (Efectivo / Cobro Manual)',
                                'virtual' => 'Pago Virtual (Nequi, PSE, Tarjeta)',
                            ])
                            ->required()
                            ->live()
                            ->default('physical'),
                    ])
                    ->columnSpanFull(),

                // ─── 4. Direcciones de Cobro ─────────────────────
                Section::make('Direcciones de Cobro')
                    ->icon('heroicon-o-map-pin')
                    ->description('Registre al menos una dirección para cobro presencial.')
                    ->hidden(fn (Get $get): bool => $get('preferred_payment_method') !== 'physical')
                    ->schema([
                        Repeater::make('addresses')
                            ->relationship('addresses')
                            ->label('')
                            ->addActionLabel('Agregar Dirección')
                            ->minItems(fn (Get $get): int => $get('preferred_payment_method') === 'physical' ? 1 : 0)
                            ->columns(2)
                            ->schema([
                                Select::make('state')
                                    ->label('Departamento')
                                    ->options(fn () => self::getDepartmentOptions())
                                    ->searchable()
                                    ->required()
                                    ->live()
                                    ->afterStateUpdated(fn (Set $set) => $set('city', null)),

                                Select::make('city')
                                    ->label('Ciudad / Municipio')
                                    ->options(function (Get $get) {
                                        $department = $get('state');
                                        if (! $department) {
                                            return [];
                                        }

                                        return DepartmentMunicipality::query()
                                            ->where('department_name', $department)
                                            ->orderBy('municipality_name')
                                            ->pluck('municipality_name', 'municipality_name')
                                            ->toArray();
                                    })
                                    ->searchable()
                                    ->required()
                                    ->disabled(fn (Get $get): bool => ! $get('state')),

                                TextInput::make('address_line_1')
                                    ->label('Dirección')
                                    ->placeholder('Ej: Calle 45 # 20-15 Barrio La Esperanza')
                                    ->required()
                                    ->maxLength(255)
                                    ->columnSpanFull(),

                                Toggle::make('is_primary')
                                    ->label('Dirección Principal')
                                    ->default(true)
                                    ->live()
                                    ->afterStateUpdated(function (bool $state, Set $set, Get $get, $component, $livewire) {
                                        if (! $state) {
                                            return;
                                        }
                                        $path = $component->getStatePath();
                                        $index = explode('.', $path)[1] ?? null;
                                        $all = $livewire->data['addresses'] ?? [];
                                        foreach ($all as $key => $addr) {
                                            if ((string) $key !== (string) $index) {
                                                $set("../../{$key}/is_primary", false);
                                            }
                                        }
                                    }),

                                Textarea::make('notes')
                                    ->label('Referencias')
                                    ->placeholder('Indicaciones para llegar, puntos de referencia...')
                                    ->rows(2)
                                    ->columnSpanFull(),
                            ])
                            ->itemLabel(fn (array $state): ?string => ! empty($state['city']) && ! empty($state['address_line_1'])
                                    ? "{$state['city']} — ".Str::limit($state['address_line_1'], 40)
                                    : ($state['address_line_1'] ?? 'Nueva dirección')
                            )
                            ->collapsible()
                            ->defaultItems(1),
                    ])
                    ->columnSpanFull(),
            ]);
    }
}
