<?php

namespace Modules\Booking\Filament\Resources\Bookings\Tables;

use Filament\Actions\ViewAction;
use Filament\Forms\Components\DatePicker;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Modules\Booking\Enums\BookingStatus;
use Modules\Booking\Filament\Resources\Bookings\Actions\AssignDriverTableAction;
use Modules\Booking\Filament\Resources\Bookings\Actions\CancelBookingTableAction;
use Modules\Booking\Models\Booking;
use Modules\Catalog\Models\EvCompany;
use Modules\Routing\Models\EvRoute;

class BookingsTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn (Builder $query) => $query->with([
                'route.company', 'route.fromDestination', 'route.toDestination', 'timeSlot', 'vehicleOptions',
            ]))
            ->defaultSort('created_at', 'desc')
            ->columns([
                TextColumn::make('booking_ref')
                    ->label('Ref')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('status')
                    ->badge()
                    ->color(fn (BookingStatus $state) => match ($state) {
                        BookingStatus::PendingPayment => 'warning',
                        BookingStatus::Confirmed => 'success',
                        BookingStatus::Cancelled => 'gray',
                        BookingStatus::Expired => 'danger',
                    }),
                TextColumn::make('route.company.name')
                    ->label('Company')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('route.fromDestination.name')
                    ->label('From'),
                TextColumn::make('route.toDestination.name')
                    ->label('To'),
                TextColumn::make('travel_date')
                    ->date()
                    ->sortable(),
                TextColumn::make('timeSlot.label')
                    ->label('Time Slot'),
                TextColumn::make('vehicleOptions')
                    ->label('Vehicle Options')
                    ->state(fn (Booking $record) => $record->vehicleOptions
                        ->map(fn ($line) => str($line->vehicle_option->value)->headline().' x'.$line->passenger_count)
                        ->all())
                    ->listWithLineBreaks(),
                TextColumn::make('price')
                    ->numeric(2)
                    ->sortable(),
                TextColumn::make('passenger_name')
                    ->label('Passenger')
                    ->description(fn (Booking $record) => $record->passenger_phone)
                    ->searchable(['passenger_name', 'passenger_phone'])
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('created_by_channel')
                    ->badge()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('driver_name')
                    ->label('Driver')
                    ->placeholder('Not yet assigned')
                    ->description(fn (Booking $record) => collect([$record->driver_phone, $record->car_plate_number, $record->car_model])
                        ->filter()
                        ->join(' • ') ?: null)
                    ->searchable(['driver_name', 'driver_phone', 'car_plate_number', 'car_model'])
                    ->toggleable(),
                TextColumn::make('created_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->options(array_combine(
                        array_map(fn (BookingStatus $status) => $status->value, BookingStatus::cases()),
                        array_map(fn (BookingStatus $status) => str($status->value)->headline()->toString(), BookingStatus::cases()),
                    )),
                Filter::make('travel_date')
                    ->schema([
                        DatePicker::make('travel_date'),
                    ])
                    ->query(fn (Builder $query, array $data) => $query->when(
                        $data['travel_date'] ?? null,
                        fn (Builder $q, $date) => $q->whereDate('travel_date', $date),
                    )),
                SelectFilter::make('ev_route_id')
                    ->label('Route')
                    ->options(fn () => EvRoute::with(['fromDestination', 'toDestination'])->get()
                        ->mapWithKeys(fn (EvRoute $route) => [
                            $route->id => "{$route->fromDestination?->name} → {$route->toDestination?->name}",
                        ]))
                    ->searchable(),
                SelectFilter::make('company')
                    ->options(fn () => EvCompany::pluck('name', 'id'))
                    ->searchable()
                    ->query(fn (Builder $query, array $data) => $query->when(
                        $data['value'] ?? null,
                        fn (Builder $q, $companyId) => $q->whereHas('route', fn (Builder $rq) => $rq->where('ev_company_id', $companyId)),
                    )),
            ])
            ->recordActions([
                ViewAction::make(),
                AssignDriverTableAction::make(),
                CancelBookingTableAction::make(),
            ]);
    }
}
