<?php

namespace App\Filament\Resources\ShippingRates\Schemas;

use App\Models\City;
use App\Models\District;
use App\Models\Province;
use App\Models\Village;
use Filament\Schemas\Schema;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Get;
use Illuminate\Validation\Rules\Unique;

class ShippingRateForm
{
    public static function configure(Schema $schema): Schema
    {
        return $schema->components([

            // --- KOTA ASAL ---
            Select::make('origin_city_id')
                ->label('Kota Asal')
                ->relationship('originCity', 'name')
                ->searchable()
                ->preload()
                ->required()
                ->live(),

            // -------------------------
            // CASCADING LOCATION INPUTS (TUJUAN)
            // -------------------------

            // 1. PROVINSI (Temp)
            Select::make('temp_province_id')
                ->label('Provinsi Tujuan')
                ->options(Province::pluck('name', 'id'))
                ->live()
                ->afterStateUpdated(function ($set) { 
                    $set('temp_city_id', null);
                    $set('temp_district_id', null);
                    $set('destination_village_id', null);
                })
                ->afterStateHydrated(function ($state, $set, $get) {
                    if ($village = Village::find($get('destination_village_id'))) {
                        $set('temp_province_id', $village->district->city->province_id);
                    }
                })
                ->dehydrated(false)
                ->searchable(),

            // 2. KOTA (Temp)
            Select::make('temp_city_id')
                ->label('Kota Tujuan')
                ->options(fn ($get) =>
                    City::where('province_id', $get('temp_province_id'))->pluck('name', 'id')
                )
                ->live()
                ->afterStateUpdated(function ($set) {
                    $set('temp_district_id', null);
                    $set('destination_village_id', null);
                })
                ->afterStateHydrated(function ($state, $set, $get) {
                    if ($village = Village::find($get('destination_village_id'))) {
                        $set('temp_city_id', $village->district->city_id);
                    }
                })
                ->disabled(fn ($get) => ! $get('temp_province_id'))
                ->dehydrated(false)
                ->searchable(),

            // 3. KECAMATAN (Temp)
            Select::make('temp_district_id')
                ->label('Kecamatan Tujuan')
                ->options(fn ($get) =>
                    District::where('city_id', $get('temp_city_id'))->pluck('name', 'id')
                )
                ->live()
                ->afterStateUpdated(fn ($set) => $set('destination_village_id', null))
                ->afterStateHydrated(function ($state, $set, $get) {
                    if ($village = Village::find($get('destination_village_id'))) {
                        $set('temp_district_id', $village->district_id);
                    }
                })
                ->disabled(fn ($get) => ! $get('temp_city_id'))
                ->dehydrated(false)
                ->searchable(),

            // 4. KELURAHAN (Final - VALIDASI FIX)
            Select::make('destination_village_id')
                ->label('Kelurahan Tujuan')
                ->options(fn ($get) => 
                    Village::query()
                        ->where('district_id', $get('temp_district_id'))
                        ->pluck('name', 'id')
                )
                ->required()
                ->searchable()
                ->disabled(fn ($get) => ! $get('temp_district_id'))
                ->unique(
                    table: 'shipping_rates',
                    column: 'destination_village_id',
                    ignoreRecord: true,
                    // PERBAIKAN DI SINI: Menghapus type hint "Get"
                    modifyRuleUsing: function (Unique $rule, $get) {
                        return $rule
                            ->where('origin_city_id', $get('origin_city_id'))
                            ->where('service_name', $get('service_name'))
                            ->where('moda', $get('moda'))
                            ->where('service_type', $get('service_type'))
                            ->where('min_weight', $get('min_weight'))
                            ->where('max_weight', $get('max_weight'));
                    }
                )
                ->validationMessages([
                    'unique' => 'Tarif untuk rute, layanan, dan berat ini sudah ada.',
                ]),

            // ------------ DETAIL LAYANAN ------------
            Select::make('service_name')
                ->label('Layanan')
                ->options([
                    'Reguler' => 'REGULER',
                ])
                ->searchable()
                ->required()
                ->live(),

            Select::make('moda')
                ->label('Moda Pengiriman')
                ->options([
                    'Udara' => 'UDARA',
                    'Laut' => 'LAUT',
                    'Darat' => 'DARAT',
                ])
                ->searchable()
                ->required()
                ->live(),

            Select::make('service_type')
                ->label('Tipe Layanan')
                ->options([
                    'Document' => 'DOCUMENT',
                    'Package' => 'PACKAGE',
                ])
                ->searchable()
                ->required()
                ->live(),
        
            TextInput::make('etd')
                ->label('Estimasi Hari (ETD)')
                ->placeholder('2-3 Hari')
                ->required(),

            TextInput::make('min_weight')
                ->label('Min. Berat (Kg)')
                ->numeric()
                ->default(1)
                ->required()
                ->live(),

            TextInput::make('max_weight')
                ->label('Max. Berat (Kg)')
                ->numeric()
                ->default(1)
                ->required()
                ->live()
                ->rule(function ($get) {
                    return function (string $attribute, $value, \Closure $fail) use ($get) {
                        $minWeight = $get('min_weight');
                        if ($minWeight !== null && $value < $minWeight) {
                            $fail('Max. Berat harus >= Min. Berat.');
                        }
                    };
                }),

            TextInput::make('price')
                ->label('Harga per Kg')
                ->numeric()
                ->prefix('Rp')
                ->required(),

            TextInput::make('price_over_weight')
                ->label('Harga/Kg Tambahan')
                ->numeric()
                ->prefix('Rp')
                ->required(),

            // ------------------ TRACKING USER ------------------
            Hidden::make('created_by')
                ->default(fn () => auth()->id()),

            Hidden::make('updated_by')
                ->default(fn () => auth()->id()),
        ]);
    }
}