<?php

namespace App\Filament\Resources\Shipments;

use App\Filament\Resources\Shipments\Pages;
use App\Filament\Resources\Shipments\RelationManagers\ConsignmentsRelationManager;
use App\Models\Shipment;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Actions;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use BackedENum;
use UnitEnum;

class ShipmentResource extends Resource
{
    protected static ?string $model          = Shipment::class;
    protected static string|BackedENum|null $navigationIcon = null;
    protected static string|UnitENum|null $navigationGroup = 'Cargo Management';
    protected static ?int    $navigationSort  = 1;

    public static function canAccess(): bool
    {
        return auth()->user()?->hasPermissionTo('view_shipments') ?? false;
    }

    public static function canCreate(): bool
    {
        return auth()->user()?->hasPermissionTo('create_shipments') ?? false;
    }

    // ── Form ──────────────────────────────────────────────────────

    public static function form(Schema $schema): Schema
    {
        return $schema->components([

            Section::make('Shipment Details')->schema([
                Grid::make(2)->schema([

                    Select::make('type')
                        ->options([
                            'air' => 'Air Freight',
                            'sea' => 'Sea Freight',
                        ])
                        ->required()
                        ->native(false)
                        ->live()
                        ->helperText('Determines how consignment charges are calculated'),

                    TextInput::make('reference')
                        ->label(fn ($get) =>
                            $get('type') === 'sea'
                                ? 'Vessel / Container Batch Ref'
                                : 'Flight Batch Ref'
                        )
                        ->placeholder(fn ($get) =>
                            $get('type') === 'sea'
                                ? 'e.g. MSC ANNA — May 2026'
                                : 'e.g. F1 — May 2026'
                        )
                        ->required()
                        ->unique(ignoreRecord: true),

                    TextInput::make('origin')
                        ->required()
                        ->placeholder('e.g. China, Turkey, Dubai'),

                    TextInput::make('destination')
                        ->required()
                        ->placeholder('e.g. KE'),

                    TextInput::make('vessel_or_flight')
                        ->label(fn ($get) =>
                            $get('type') === 'sea'
                                ? 'Vessel Name'
                                : 'Flight Number'
                        )
                        ->nullable(),

                    Select::make('status')
                        ->options(self::shipmentStatusOptions())
                        ->required()
                        ->native(false)
                        ->default('in_transit')
                        ->helperText(
                            'Updating this cascades to all consignees ' .
                            'that are still in transit.'
                        ),
                ]),
            ]),

            Section::make('Dates')->schema([
                Grid::make(3)->schema([
                    DatePicker::make('departure_date')->nullable(),
                    DatePicker::make('eta')->label('ETA (Estimated Arrival)')->nullable(),
                    DatePicker::make('ata')->label('ATA (Actual Arrival)')->nullable(),
                ]),
            ]),

            Section::make('Notes')->schema([
                Textarea::make('notes')
                    ->rows(3)
                    ->nullable()
                    ->columnSpanFull(),
            ])->collapsed(),

        ]);
    }

    // ── Table ─────────────────────────────────────────────────────

    public static function table(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn ($query) =>
                $query->withCount('consignments')
            )
            ->columns([
                Tables\Columns\TextColumn::make('reference')
                    ->label('Ref / Batch')
                    ->searchable()
                    ->copyable()
                    ->weight('bold'),

                Tables\Columns\TextColumn::make('type')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'air'   => 'info',
                        'sea'   => 'warning',
                        default => 'gray',
                    }),

                Tables\Columns\TextColumn::make('origin')
                    ->formatStateUsing(fn ($record) =>
                        "{$record->origin} → {$record->destination}"
                    )
                    ->label('Route'),

                Tables\Columns\TextColumn::make('status')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'in_transit'       => 'info',
                        'arrived'          => 'warning',
                        'customs_clearance' => 'danger',
                        'in_warehouse'     => 'success',
                        default            => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string =>
                        ucwords(str_replace('_', ' ', $state))
                    ),

                Tables\Columns\TextColumn::make('eta')
                    ->label('ETA')
                    ->date('M d, Y')
                    ->sortable()
                    ->placeholder('—'),

                Tables\Columns\TextColumn::make('consignments_count')
                    ->label('Consignees')
                    ->badge()
                    ->color('gray'),

                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime('M d, Y')
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('type')
                    ->options(['air' => 'Air', 'sea' => 'Sea']),

                Tables\Filters\SelectFilter::make('status')
                    ->options(self::shipmentStatusOptions()),
            ])
            ->actions([
                EditAction::make(),

                Action::make('update_status')
                    ->label('Update Status')
                    ->icon('heroicon-o-arrow-path')
                    ->color('warning')
                    ->form([
                        Select::make('status')
                            ->options(self::shipmentStatusOptions())
                            ->required()
                            ->native(false),
                        Textarea::make('note')
                            ->label('Note (optional)')
                            ->rows(2),
                    ])
                    ->action(function (Shipment $record, array $data): void {
                        $record->update(['status' => $data['status']]);
                        $record->syncConsignmentStatuses();

                        Notification::make()
                            ->title('Shipment status updated')
                            ->success()
                            ->send();
                    }),

                Action::make('mark_all_in_warehouse')
                    ->label('Mark All In Warehouse')
                    ->icon('heroicon-o-building-storefront')
                    ->color('success')
                    ->requiresConfirmation()
                    ->modalHeading('Mark all consignees as arrived in warehouse?')
                    ->modalDescription(
                        'All consignees in transit will be moved to In Warehouse. ' .
                        'This logs a stock IN movement for each one.'
                    )
                    ->action(function (Shipment $record): void {
                        $record->consignments()
                            ->where('status', 'in_transit')
                            ->each(function ($c) {
                                $c->update(['status' => 'in_warehouse']);

                                \App\Models\StockMovement::create([
                                    'consignment_id' => $c->id,
                                    'type'           => 'IN',
                                    'notes'          => 'Arrived in warehouse (bulk)',
                                    'moved_by'       => auth()->id(),
                                    'moved_at'       => now(),
                                ]);

                                \App\Models\ConsignmentStatusHistory::create([
                                    'consignment_id' => $c->id,
                                    'status'         => 'in_warehouse',
                                    'note'           => 'Shipment arrived — goods in warehouse',
                                    'changed_by'     => auth()->id(),
                                ]);
                            });

                        $record->update(['status' => 'in_warehouse']);

                        Notification::make()
                            ->title('All consignees marked in warehouse')
                            ->success()
                            ->send();
                    }),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make(),
                ]),
            ])
            ->defaultSort('created_at', 'desc');
    }

    public static function getRelations(): array
    {
        return [
            ConsignmentsRelationManager::class,
        ];
    }

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

    public static function shipmentStatusOptions(): array
    {
        return [
            'in_transit'        => 'In Transit',
            'arrived'           => 'Arrived',
            'customs_clearance' => 'Customs Clearance',
            'in_warehouse'      => 'In Warehouse',
        ];
    }

    public static function allStatusOptions(): array
    {
        return [
            'in_transit'       => 'In Transit',
            'arrived'          => 'Arrived',
            'customs_clearance' => 'Customs Clearance',
            'in_warehouse'     => 'In Warehouse',
            'ready_for_pickup' => 'Ready for Pickup',
            'delivered'        => 'Delivered',
        ];
    }

    public static function canDeleteAny(): bool
    {
        return auth()->user()?->hasRole(['super_admin', 'admin']) ?? false;
    }
}