<?php

declare(strict_types=1);

namespace App\Filament\Resources;

use App\Filament\Resources\VehicleResource\Pages;
use App\Filament\Resources\VehicleResource\RelationManagers\JobsRelationManager;
use App\Filament\Resources\VehicleResource\RelationManagers\MaintenanceLogsRelationManager;
use App\Models\Vehicle;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;

class VehicleResource extends Resource
{
    protected static ?string $model = Vehicle::class;

    protected static ?string $navigationIcon  = 'heroicon-o-truck';
    protected static ?string $navigationGroup = 'Fleet';
    protected static ?string $navigationLabel = 'Vehicles';
    protected static ?int    $navigationSort  = 2;

    public static function getModelLabel(): string
    {
        return 'Vehicle';
    }

    public static function getPluralModelLabel(): string
    {
        return 'Vehicles';
    }

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Key maintenance info (COF, rego, service, RUC, current kms)
                Forms\Components\Section::make('Key maintenance info')
                    ->description('Set key dates so you can see upcoming COF, rego, RUC and service.')
                    ->columns(5)
                    ->schema([
                        // COF expiry
                        Forms\Components\DatePicker::make('cof_due_at')
                            ->label('COF expiry')
                            ->native(false)
                            ->closeOnDateSelection()
                            ->disabled(fn (?Vehicle $record) => $record && $record->exists)
                            ->hint(function (Get $get) {
                                $value = $get('cof_due_at');
                                if (! $value) {
                                    return 'Not set';
                                }

                                $date  = Carbon::parse($value)->startOfDay();
                                $today = now()->startOfDay();

                                if ($date->lt($today)) {
                                    return 'COF is OVERDUE';
                                }

                                $days = $today->diffInDays($date);
                                if ($days <= 28) {
                                    return "Due in {$days} day" . ($days === 1 ? '' : 's');
                                }

                                return 'OK';
                            })
                            ->hintColor(function (Get $get) {
                                $value = $get('cof_due_at');
                                if (! $value) {
                                    return 'secondary';
                                }

                                $date  = Carbon::parse($value)->startOfDay();
                                $today = now()->startOfDay();

                                if ($date->lt($today)) {
                                    return 'danger';
                                }

                                $days = $today->diffInDays($date);
                                if ($days <= 28) {
                                    return 'warning';
                                }

                                return 'success';
                            }),

                        // Rego expiry
                        Forms\Components\DatePicker::make('rego_due_at')
                            ->label('Rego expiry')
                            ->native(false)
                            ->closeOnDateSelection()
                            ->disabled(fn (?Vehicle $record) => $record && $record->exists)
                            ->hint(function (Get $get) {
                                $value = $get('rego_due_at');
                                if (! $value) {
                                    return 'Not set';
                                }

                                $date  = Carbon::parse($value)->startOfDay();
                                $today = now()->startOfDay();

                                if ($date->lt($today)) {
                                    return 'Rego is OVERDUE';
                                }

                                $days = $today->diffInDays($date);
                                if ($days <= 28) {
                                    return "Due in {$days} day" . ($days === 1 ? '' : 's');
                                }

                                return 'OK';
                            })
                            ->hintColor(function (Get $get) {
                                $value = $get('rego_due_at');
                                if (! $value) {
                                    return 'secondary';
                                }

                                $date  = Carbon::parse($value)->startOfDay();
                                $today = now()->startOfDay();

                                if ($date->lt($today)) {
                                    return 'danger';
                                }

                                $days = $today->diffInDays($date);
                                if ($days <= 28) {
                                    return 'warning';
                                }

                                return 'success';
                            }),

                        // Next service due (km)
                        Forms\Components\TextInput::make('service_due_km')
                            ->label('Next service due (km)')
                            ->numeric()
                            ->minValue(0)
                            ->disabled(fn (?Vehicle $record) => $record && $record->exists)
                            ->hint(function (Get $get) {
                                $serviceDue = $get('service_due_km');
                                $current    = $get('odometer_km');

                                if (! $serviceDue) {
                                    return 'Not set';
                                }

                                if (! $current) {
                                    return 'Set current mileage to see distance remaining';
                                }

                                $remaining = (int) $serviceDue - (int) $current;

                                if ($remaining <= 0) {
                                    return number_format(abs($remaining)) . ' km OVERDUE';
                                }

                                if ($remaining <= 5000) {
                                    return number_format($remaining) . ' km to go (due soon)';
                                }

                                return number_format($remaining) . ' km to go';
                            })
                            ->hintColor(function (Get $get) {
                                $serviceDue = $get('service_due_km');
                                $current    = $get('odometer_km');

                                if (! $serviceDue || ! $current) {
                                    return 'secondary';
                                }

                                $remaining = (int) $serviceDue - (int) $current;

                                if ($remaining <= 0) {
                                    return 'danger';
                                }

                                if ($remaining <= 5000) {
                                    return 'warning';
                                }

                                return 'success';
                            }),

                        // RUC paid to (km)
                        Forms\Components\TextInput::make('ruc_paid_to_km')
                            ->label('RUC paid to (km)')
                            ->numeric()
                            ->minValue(0)
                            ->hint(function (Get $get) {
                                $rucPaidTo = $get('ruc_paid_to_km');
                                $current   = $get('odometer_km');

                                if (! $rucPaidTo) {
                                    return 'Not set';
                                }

                                if (! $current) {
                                    return 'Set current mileage to see remaining RUC';
                                }

                                $remaining = (int) $rucPaidTo - (int) $current;

                                if ($remaining <= 0) {
                                    return number_format(abs($remaining)) . ' km OVERDUE';
                                }

                                if ($remaining <= 2000) {
                                    return number_format($remaining) . ' km remaining (top up soon)';
                                }

                                return number_format($remaining) . ' km remaining';
                            })
                            ->hintColor(function (Get $get) {
                                $rucPaidTo = $get('ruc_paid_to_km');
                                $current   = $get('odometer_km');

                                if (! $rucPaidTo || ! $current) {
                                    return 'secondary';
                                }

                                $remaining = (int) $rucPaidTo - (int) $current;

                                if ($remaining <= 0) {
                                    return 'danger';
                                }

                                if ($remaining <= 2000) {
                                    return 'warning';
                                }

                                return 'success';
                            }),

                        // Current mileage
                        Forms\Components\TextInput::make('odometer_km')
                            ->label('Current mileage (km)')
                            ->numeric()
                            ->minValue(0)
                            ->helperText('Update this regularly so service and RUC warnings stay accurate.'),
                    ]),

                // Basic details
                Forms\Components\Section::make('Basic details')
                    ->columns(3)
                    ->schema([
                        Forms\Components\TextInput::make('name')
                            ->label('Name / Display name')
                            ->required()
                            ->maxLength(255),

                        Forms\Components\TextInput::make('registration')
                            ->label('Registration')
                            ->maxLength(50)
                            ->nullable(),

                        Forms\Components\Select::make('type')
                            ->label('Vehicle type')
                            ->options([
                                'jimny_3door' => 'Jimny 3-door',
                                'jimny_5door' => 'Jimny 5-door',
                                'suv'         => 'SUV',
                                'sports'      => 'Sports car',
                                'ev'          => 'EV',
                                'van'         => 'Van',
                            ])
                            ->searchable()
                            ->nullable()
                            ->helperText('Used for pricing and portal selection.'),

                        Forms\Components\TextInput::make('year')
                            ->numeric()
                            ->minValue(1900)
                            ->maxValue(now()->year + 1)
                            ->nullable(),

                        Forms\Components\TextInput::make('make')
                            ->label('Make')
                            ->maxLength(100)
                            ->nullable(),

                        Forms\Components\TextInput::make('model')
                            ->label('Model')
                            ->maxLength(100)
                            ->nullable(),

                        Forms\Components\TextInput::make('colour')
                            ->label('Colour')
                            ->maxLength(100)
                            ->nullable(),

                        Forms\Components\TextInput::make('vevs_vehicle_id')
                            ->label('VEVS vehicle ID')
                            ->maxLength(100)
                            ->helperText('Optional – used to match VEVS bookings to this vehicle.')
                            ->nullable(),

                        Forms\Components\Toggle::make('is_active')
                            ->label('Active')
                            ->default(true),
                    ]),

                // Ownership / consignment
                Forms\Components\Section::make('Ownership')
                    ->description('Set whether this vehicle is company-owned or consignment and link it to an owner.')
                    ->columns(2)
                    ->schema([
                        Forms\Components\Select::make('ownership_type')
                            ->label('Ownership type')
                            ->options([
                                'company_owned' => 'Company owned',
                                'consignment'   => 'Consignment',
                                'other'         => 'Other',
                            ])
                            ->required(),

                        Forms\Components\Select::make('owner_id')
                            ->label('Owner')
                            ->relationship('owner', 'name')
                            ->searchable()
                            ->preload()
                            ->visible(fn (Get $get) => $get('ownership_type') === 'consignment')
                            ->helperText('Select the owner for consignment vehicles, or leave blank for company-owned.'),

                        Forms\Components\TextInput::make('owner_share_percent')
                            ->label('Owner revenue share (%)')
                            ->numeric()
                            ->minValue(0)
                            ->maxValue(100)
                            ->default(70)
                            ->helperText('Percentage of job revenue allocated to the owner.')
                            ->visible(fn (Get $get) => (bool) $get('owner_id'))
                            ->required(fn (Get $get) => (bool) $get('owner_id')),
                    ]),

                // Fleet admin / operational details
                Forms\Components\Section::make('Fleet admin details')
                    ->description('Operational details to replace the fleet spreadsheet.')
                    ->columns(2)
                    ->schema([
                        Forms\Components\TextInput::make('rego_type')
                            ->label('Rego type (L / G)')
                            ->maxLength(20)
                            ->nullable(),

                        Forms\Components\TextInput::make('lockbox_code')
                            ->label('Lockbox code / number')
                            ->maxLength(50)
                            ->nullable(),

                        Forms\Components\TextInput::make('gps_phone_number')
                            ->label('GPS phone number')
                            ->maxLength(50)
                            ->nullable(),

                        Forms\Components\TextInput::make('gps_topup_note')
                            ->label('GPS topup note')
                            ->maxLength(255)
                            ->helperText('E.g. “Topped up $20 on 12/11/25”')
                            ->nullable(),

                        Forms\Components\TextInput::make('insurance_provider')
                            ->label('Insurance provider')
                            ->maxLength(100)
                            ->nullable(),

                        Forms\Components\Textarea::make('appointments_note')
                            ->label('Appointments / notes')
                            ->rows(2)
                            ->nullable(),
                    ]),

                // Specs & Notes
                Forms\Components\Section::make('Specs & Notes')
                    ->columns(2)
                    ->schema([
                        Forms\Components\TextInput::make('seats')
                            ->numeric()
                            ->minValue(1)
                            ->maxValue(9)
                            ->label('Seats')
                            ->nullable(),

                        Forms\Components\Textarea::make('notes')
                            ->label('Notes')
                            ->rows(4)
                            ->columnSpanFull()
                            ->nullable(),
                    ]),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                // Vehicle identifier
                Tables\Columns\TextColumn::make('display_label')
                    ->label('Vehicle')
                    ->searchable()
                    ->sortable(),

                Tables\Columns\TextColumn::make('type')
                    ->label('Type')
                    ->badge()
                    ->sortable()
                    ->formatStateUsing(function (?string $state) {
                        return match ($state) {
                            'jimny_3door' => 'Jimny 3-door',
                            'jimny_5door' => 'Jimny 5-door',
                            'suv'         => 'SUV',
                            'sports'      => 'Sports car',
                            'ev'          => 'EV',
                            'van'         => 'Van',
                            default       => $state ?: '—',
                        };
                    }),

                Tables\Columns\TextColumn::make('vevs_vehicle_id')
                    ->label('VEVS vehicle ID')
                    ->searchable()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),

                // Owner + share
                Tables\Columns\TextColumn::make('owner.name')
                    ->label('Owner')
                    ->toggleable()
                    ->sortable(),

                Tables\Columns\TextColumn::make('owner_share_percent')
                    ->label('Owner %')
                    ->suffix('%')
                    ->alignment('right')
                    ->toggleable()
                    ->sortable(),

                // COF due
                Tables\Columns\TextColumn::make('cof_due_at')
                    ->label('COF due')
                    ->date('d M Y')
                    ->sortable()
                    ->formatStateUsing(fn ($state) => $state ? $state->format('d M Y') : '—')
                    ->color(function ($state) {
                        if (! $state) {
                            return null;
                        }

                        $today = now()->startOfDay();

                        if ($state->lt($today)) {
                            return 'danger';
                        }

                        if ($state->between($today, $today->copy()->addDays(28))) {
                            return 'warning';
                        }

                        return null;
                    }),

                // Rego due
                Tables\Columns\TextColumn::make('rego_due_at')
                    ->label('Rego due')
                    ->date('d M Y')
                    ->sortable()
                    ->formatStateUsing(fn ($state) => $state ? $state->format('d M Y') : '—')
                    ->color(function ($state) {
                        if (! $state) {
                            return null;
                        }

                        $today = now()->startOfDay();

                        if ($state->lt($today)) {
                            return 'danger';
                        }

                        if ($state->between($today, $today->copy()->addDays(28))) {
                            return 'warning';
                        }

                        return null;
                    }),

                // RUC status
                Tables\Columns\TextColumn::make('ruc_paid_to_km')
                    ->label('RUC paid to (km)')
                    ->sortable()
                    ->formatStateUsing(fn ($state) => $state ? number_format($state) : '—')
                    ->description(function ($state, Vehicle $record) {
                        if (! $state || ! $record->odometer_km) {
                            return null;
                        }

                        $remaining = (int) $state - (int) $record->odometer_km;

                        return $remaining > 0
                            ? number_format($remaining) . ' km remaining'
                            : number_format(abs($remaining)) . ' km OVERDUE';
                    })
                    ->color(function ($state, Vehicle $record) {
                        if (! $state || ! $record->odometer_km) {
                            return null;
                        }

                        $remaining = (int) $state - (int) $record->odometer_km;

                        if ($remaining <= 0) {
                            return 'danger';
                        }

                        if ($remaining <= 2000) {
                            return 'warning';
                        }

                        return null;
                    }),

                // Service due
                Tables\Columns\TextColumn::make('service_due_km')
                    ->label('Service due (km)')
                    ->sortable()
                    ->formatStateUsing(fn ($state) => $state ? number_format($state) : '—')
                    ->description(function ($state, Vehicle $record) {
                        if (! $state || ! $record->odometer_km) {
                            return null;
                        }

                        $remaining = (int) $state - (int) $record->odometer_km;

                        return $remaining > 0
                            ? number_format($remaining) . ' km to go'
                            : number_format(abs($remaining)) . ' km OVERDUE';
                    })
                    ->color(function ($state, Vehicle $record) {
                        if (! $state || ! $record->odometer_km) {
                            return null;
                        }

                        $remaining = (int) $state - (int) $record->odometer_km;

                        if ($remaining <= 0) {
                            return 'danger';
                        }

                        if ($remaining <= 5000) {
                            return 'warning';
                        }

                        return null;
                    }),
            ])
            ->filters([
                Tables\Filters\TernaryFilter::make('is_active')
                    ->label('Active'),

                Tables\Filters\SelectFilter::make('type')
                    ->label('Type')
                    ->options([
                        'jimny_3door' => 'Jimny 3-door',
                        'jimny_5door' => 'Jimny 5-door',
                        'suv'         => 'SUV',
                        'sports'      => 'Sports car',
                        'ev'          => 'EV',
                        'van'         => 'Van',
                    ]),

                // "Needs attention" – anything close or overdue
                Filter::make('needs_attention')
                    ->label('Needs attention')
                    ->query(function (Builder $query) {
                        $today = now()->startOfDay();
                        $near  = $today->copy()->addDays(28);

                        $query->where(function (Builder $q) use ($today, $near) {
                            $q->whereDate('cof_due_at', '<', $today)
                              ->orWhereBetween('cof_due_at', [$today, $near])
                              ->orWhereDate('rego_due_at', '<', $today)
                              ->orWhereBetween('rego_due_at', [$today, $near])
                              ->orWhere(function (Builder $q2) {
                                  $q2->whereNotNull('service_due_km')
                                     ->whereNotNull('odometer_km')
                                     ->whereRaw('(service_due_km - odometer_km) <= 5000');
                              })
                              ->orWhere(function (Builder $q3) {
                                  $q3->whereNotNull('ruc_paid_to_km')
                                     ->whereNotNull('odometer_km')
                                     ->whereRaw('(ruc_paid_to_km - odometer_km) <= 2000');
                              });
                        });
                    }),
            ])
            ->actions([
                Tables\Actions\EditAction::make(),

                Tables\Actions\Action::make('update_maintenance')
                    ->label('Update maintenance')
                    ->icon('heroicon-o-wrench')
                    ->url(fn (Vehicle $record) => static::getUrl('edit', ['record' => $record]))
                    ->tooltip('Open vehicle and add a maintenance log'),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ]);
    }

    public static function getRelations(): array
    {
        return [
            MaintenanceLogsRelationManager::class,
            JobsRelationManager::class,
            \App\Filament\Resources\VehicleResource\RelationManagers\DamagesRelationManager::class,
        ];
    }

    public static function getPages(): array
    {
        return [
            'index'  => Pages\ListVehicles::route('/'),
            'create' => Pages\CreateVehicle::route('/create'),
            'edit'   => Pages\EditVehicle::route('/{record}/edit'),
        ];
    }
}
