<?php

namespace App\Filament\Resources\Orders\Tables;

use App\Models\Order;
use App\Models\Setting;
use App\Services\CourierService;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\BulkAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Tables\Table;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Builder;

class OrdersTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('order_number')
                    ->label('Number')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('customer_name')
                    ->label('Customer')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('status')
                    ->label('Status')
                    ->badge()
                    ->state(function (Order $record): array {
                        $badges = [];
                        $badges[] = $record->status;
                        if ($record->is_exchange || $record->childOrders->isNotEmpty()) {
                            $badges[] = 'exchange';
                        }
                        return $badges;
                    })
                    ->color(fn (string $state): string => match ($state) {
                        'pending' => 'info',
                        'processing' => 'warning',
                        'shipped' => 'info',
                        'delivered' => 'success',
                        'cancelled' => 'danger',
                        'returned' => 'purple',
                        'exchange' => 'success',
                        default => 'gray',
                    })
                    ->icon(fn (string $state): ?string => match ($state) {
                        'pending' => 'heroicon-m-sparkles',
                        'processing' => 'heroicon-m-arrow-path',
                        'shipped' => 'heroicon-m-truck',
                        'delivered' => 'heroicon-m-check-circle',
                        'cancelled' => 'heroicon-m-x-circle',
                        'returned' => 'heroicon-m-arrow-uturn-left',
                        'exchange' => 'heroicon-m-arrow-path-rounded-square',
                        default => null,
                    })
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        'pending' => 'New',
                        'returned' => 'Returned',
                        'exchange' => 'Exchange',
                        default => ucfirst($state),
                    })
                    ->sortable(),
                TextColumn::make('grand_total')
                    ->label('Total price')
                    ->money('BDT')
                    ->alignEnd()
                    ->sortable(),
                TextColumn::make('shipping_cost')
                    ->label('Shipping cost')
                    ->money('BDT')
                    ->alignEnd()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('created_at')
                    ->label('Order date')
                    ->date('M j, Y')
                    ->sortable()
                    ->toggleable(),
            ])
            ->defaultSort('created_at', 'desc')
            ->filters([
                // Filter by Order Status
                SelectFilter::make('status')
                    ->options([
                        'pending' => 'Pending',
                        'processing' => 'Processing',
                        'shipped' => 'Shipped',
                        'delivered' => 'Delivered',
                        'cancelled' => 'Cancelled',
                        'returned' => 'Returned',
                    ]),

                // Filter by Payment Status
                SelectFilter::make('payment_status')
                    ->options([
                        'pending' => 'Pending',
                        'paid' => 'Paid',
                        'failed' => 'Failed',
                        'refunded' => 'Refunded',
                    ]),

                // Filter by Payment Method
                SelectFilter::make('payment_method')
                    ->options([
                        'cod' => 'Cash On Delivery (COD)',
                        'sslcommerz' => 'SSLCommerz',
                        'bkash' => 'bKash',
                        'nagad' => 'Nagad',
                    ]),

                // Filter by Courier Booking State
                TernaryFilter::make('has_courier_booking')
                    ->label('Has Courier Booking')
                    ->queries(
                        true: fn (Builder $query) => $query->whereHas('courierBooking'),
                        false: fn (Builder $query) => $query->whereDoesntHave('courierBooking'),
                    ),

                // Filter by Ordered Date Range
                Filter::make('created_at')
                    ->form([
                        DatePicker::make('created_from')
                            ->label('Ordered From'),
                        DatePicker::make('created_until')
                            ->label('Ordered Until'),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['created_from'],
                                fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date),
                            )
                            ->when(
                                $data['created_until'],
                                fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date),
                            );
                    })
            ])
            ->actions([
                ActionGroup::make([
                    EditAction::make(),
                    
                    Action::make('update_status')
                        ->label('Update Status')
                        ->icon('heroicon-o-check-circle')
                        ->color('primary')
                        ->modalWidth('sm')
                        ->form([
                            Select::make('status')
                                ->label('Status')
                                ->options([
                                    'pending' => 'Pending',
                                    'processing' => 'Processing',
                                    'shipped' => 'Shipped',
                                    'delivered' => 'Delivered',
                                    'cancelled' => 'Cancelled',
                                    'returned' => 'Returned',
                                ])
                                ->default(fn (Order $record) => $record->status)
                                ->required(),
                        ])
                        ->action(function (Order $record, array $data): void {
                            $oldStatus = $record->status;
                            if ($oldStatus === $data['status']) {
                                return;
                            }
                            $record->update(['status' => $data['status']]);
                            $record->histories()->create([
                                'user_id' => auth()->id(),
                                'action' => 'status_changed',
                                'from_status' => $oldStatus,
                                'to_status' => $data['status'],
                                'notes' => 'Status updated to ' . $data['status'] . ' via quick action.',
                            ]);
                            try {
                                \App\Services\NotificationDispatcher::dispatchForOrder($record, $data['status']);
                            } catch (\Exception $e) {
                                // Silence notifications error
                            }

                            Notification::make()
                                ->title('Order Status Updated')
                                ->success()
                                ->send();
                        }),

                    Action::make('one_click_ship')
                        ->label('One-Click Ship')
                        ->icon('heroicon-o-truck')
                        ->color('primary')
                        ->modalWidth('sm')
                        ->visible(fn (Order $record): bool => in_array($record->status, ['pending', 'processing']) && !$record->courierBooking()->exists())
                        ->mountUsing(function ($action, Order $record) {
                            $defaultCourier = Setting::getValue('default_courier');
                            $isDefaultActive = false;
                            if ($defaultCourier === 'steadfast') {
                                $isDefaultActive = Setting::getValue('steadfast_enabled') === 'on' || Setting::getValue('steadfast_enabled') === true || Setting::getValue('steadfast_enabled') === '1' || Setting::getValue('steadfast_enabled') === 1;
                            } elseif ($defaultCourier === 'pathao') {
                                $isDefaultActive = Setting::getValue('pathao_enabled') === 'on' || Setting::getValue('pathao_enabled') === true || Setting::getValue('pathao_enabled') === '1' || Setting::getValue('pathao_enabled') === 1;
                            }

                            if ($isDefaultActive) {
                                $result = CourierService::bookConsignment($record, $defaultCourier);
                                if ($result['success']) {
                                    Notification::make()
                                        ->title('Shipment Booked')
                                        ->body($result['message'])
                                        ->success()
                                        ->send();
                                } else {
                                    Notification::make()
                                        ->title('Booking Failed')
                                        ->body($result['message'])
                                        ->danger()
                                        ->send();
                                }
                                $action->cancel();
                            }
                        })
                        ->form([
                            Select::make('courier')
                                ->label('Select Courier')
                                ->options(function () {
                                    $options = [];
                                    if (Setting::getValue('steadfast_enabled') === 'on' || Setting::getValue('steadfast_enabled') === true || Setting::getValue('steadfast_enabled') === '1' || Setting::getValue('steadfast_enabled') === 1) {
                                        $options['steadfast'] = 'Steadfast Courier';
                                    }
                                    if (Setting::getValue('pathao_enabled') === 'on' || Setting::getValue('pathao_enabled') === true || Setting::getValue('pathao_enabled') === '1' || Setting::getValue('pathao_enabled') === 1) {
                                        $options['pathao'] = 'Pathao Courier';
                                    }
                                    return $options;
                                })
                                ->default(fn () => Setting::getValue('default_courier', 'steadfast'))
                                ->required(),
                        ])
                        ->action(function (Order $record, array $data) {
                            $result = CourierService::bookConsignment($record, $data['courier']);
                            if ($result['success']) {
                                Notification::make()
                                    ->title('Shipment Booked')
                                    ->body($result['message'])
                                    ->success()
                                    ->send();
                            } else {
                                Notification::make()
                                    ->title('Booking Failed')
                                    ->body($result['message'])
                                    ->danger()
                                    ->send();
                            }
                        }),
                    Action::make('download_invoice')
                        ->label('Invoice')
                        ->icon('heroicon-o-arrow-down-tray')
                        ->color('info')
                        ->url(fn (Order $record): string => route('orders.invoice', ['order' => $record->id]))
                        ->openUrlInNewTab(),

                    DeleteAction::make(),
                ])
                ->color('info'),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    // Bulk Status Updates
                    BulkAction::make('bulk_status_update')
                        ->label('Update Status')
                        ->icon('heroicon-o-check-circle')
                        ->color('primary')
                        ->form([
                            Select::make('status')
                                ->label('Select Status')
                                ->options([
                                    'pending' => 'Pending',
                                    'processing' => 'Processing',
                                    'shipped' => 'Shipped',
                                    'delivered' => 'Delivered',
                                    'cancelled' => 'Cancelled',
                                    'returned' => 'Returned',
                                ])
                                ->required(),
                        ])
                        ->action(function (\Illuminate\Support\Collection $records, array $data): void {
                            foreach ($records as $record) {
                                $oldStatus = $record->status;
                                $record->update(['status' => $data['status']]);
                                $record->histories()->create([
                                    'user_id' => auth()->id(),
                                    'action' => 'status_changed',
                                    'from_status' => $oldStatus,
                                    'to_status' => $data['status'],
                                    'notes' => 'Status bulk-updated to ' . $data['status'] . ' by administrator.',
                                ]);
                                try {
                                    \App\Services\NotificationDispatcher::dispatchForOrder($record, $data['status']);
                                } catch (\Exception $e) {
                                    // Fallback if notifications fail
                                }
                            }
                            Notification::make()
                                ->title('Orders Updated')
                                ->body('Status updated successfully for ' . $records->count() . ' orders.')
                                ->success()
                                ->send();
                        }),

                    // Bulk Print Invoices
                    BulkAction::make('bulk_print_invoices')
                        ->label('Print Invoices')
                        ->icon('heroicon-o-printer')
                        ->color('info')
                        ->action(function (\Illuminate\Support\Collection $records) {
                            $ids = $records->pluck('id')->implode(',');
                            return redirect()->away(route('orders.invoice.bulk', ['ids' => $ids]));
                        }),

                    // Bulk One-Click Ship
                    BulkAction::make('bulk_one_click_ship')
                        ->label('One-Click Ship')
                        ->icon('heroicon-o-truck')
                        ->color('primary')
                        ->modalWidth('sm')
                        ->mountUsing(function ($action, \Illuminate\Support\Collection $records) {
                            $defaultCourier = Setting::getValue('default_courier');
                            $isDefaultActive = false;
                            if ($defaultCourier === 'steadfast') {
                                $isDefaultActive = Setting::getValue('steadfast_enabled') === 'on' || Setting::getValue('steadfast_enabled') === true || Setting::getValue('steadfast_enabled') === '1' || Setting::getValue('steadfast_enabled') === 1;
                            } elseif ($defaultCourier === 'pathao') {
                                $isDefaultActive = Setting::getValue('pathao_enabled') === 'on' || Setting::getValue('pathao_enabled') === true || Setting::getValue('pathao_enabled') === '1' || Setting::getValue('pathao_enabled') === 1;
                            }

                            if ($isDefaultActive) {
                                $successCount = 0;
                                $failCount = 0;
                                $messages = [];

                                foreach ($records as $record) {
                                    if (!in_array($record->status, ['pending', 'processing']) || $record->courierBooking()->exists()) {
                                        $failCount++;
                                        continue;
                                    }

                                    $result = CourierService::bookConsignment($record, $defaultCourier);
                                    if ($result['success']) {
                                        $successCount++;
                                    } else {
                                        $failCount++;
                                        $messages[] = "Order #{$record->order_number}: {$result['message']}";
                                    }
                                }

                                if ($successCount > 0) {
                                    Notification::make()
                                        ->title('Bulk Shipment Booked')
                                        ->body("Successfully booked shipment for {$successCount} order(s) via " . ($defaultCourier === 'steadfast' ? 'Steadfast' : 'Pathao') . ".")
                                        ->success()
                                        ->send();
                                }

                                if ($failCount > 0) {
                                    $failBody = "Failed to book shipment for {$failCount} order(s).";
                                    if (count($messages) > 0) {
                                        $failBody .= " Errors: " . implode('; ', array_slice($messages, 0, 3));
                                    }
                                    Notification::make()
                                        ->title('Some Bookings Failed')
                                        ->body($failBody)
                                        ->danger()
                                        ->send();
                                }

                                $action->cancel();
                            }
                        })
                        ->form([
                            Select::make('courier')
                                ->label('Select Courier')
                                ->options(function () {
                                    $options = [];
                                    if (Setting::getValue('steadfast_enabled') === 'on' || Setting::getValue('steadfast_enabled') === true || Setting::getValue('steadfast_enabled') === '1' || Setting::getValue('steadfast_enabled') === 1) {
                                        $options['steadfast'] = 'Steadfast Courier';
                                    }
                                    if (Setting::getValue('pathao_enabled') === 'on' || Setting::getValue('pathao_enabled') === true || Setting::getValue('pathao_enabled') === '1' || Setting::getValue('pathao_enabled') === 1) {
                                        $options['pathao'] = 'Pathao Courier';
                                    }
                                    return $options;
                                })
                                ->default(fn () => Setting::getValue('default_courier', 'steadfast'))
                                ->required(),
                        ])
                        ->action(function (\Illuminate\Support\Collection $records, array $data): void {
                            $courier = $data['courier'];
                            $successCount = 0;
                            $failCount = 0;
                            $messages = [];

                            foreach ($records as $record) {
                                if (!in_array($record->status, ['pending', 'processing']) || $record->courierBooking()->exists()) {
                                    $failCount++;
                                    continue;
                                }

                                $result = CourierService::bookConsignment($record, $courier);
                                if ($result['success']) {
                                    $successCount++;
                                } else {
                                    $failCount++;
                                    $messages[] = "Order #{$record->order_number}: {$result['message']}";
                                }
                            }

                            if ($successCount > 0) {
                                Notification::make()
                                    ->title('Bulk Shipment Booked')
                                    ->body("Successfully booked shipment for {$successCount} order(s) via " . ($courier === 'steadfast' ? 'Steadfast' : 'Pathao') . ".")
                                    ->success()
                                    ->send();
                            }

                            if ($failCount > 0) {
                                $failBody = "Failed to book shipment for {$failCount} order(s).";
                                if (count($messages) > 0) {
                                    $failBody .= " Errors: " . implode('; ', array_slice($messages, 0, 3));
                                }
                                Notification::make()
                                    ->title('Some Bookings Failed')
                                    ->body($failBody)
                                    ->danger()
                                    ->send();
                            }
                        }),

                    DeleteBulkAction::make(),
                ]),
            ]);
    }
}
