<?php

declare(strict_types=1);

namespace App\Filament\Resources\Projects\Tables;

use App\Filament\Support\SelectOptionLabels;

use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Notifications\Notification;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Project;

class ProjectsTable
{
    public static function getStatusOptions(): array
    {
        return [
            'pending' => 'در انتظار',
            'active' => 'فعال',
            'approved' => 'تایید',
            'rejected' => 'رد',
            'edit' => 'ویرایش',
            'waiting' => 'انتظار',
            'arbitration' => 'داوری',
            'unsigned' => 'امضا نشده',
            'completed' => 'تکمیل شده',
            'cancelled' => 'لغو شده',
            'expired' => 'منقضی شده',
        ];
    }

    public static function configure(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn (Builder $query): Builder => $query->with([
                'user',
                'producer.user',
                'category',
                'createdBy',
            ]))
            ->columns([
                TextColumn::make('code')
                    ->label('کد')
                    ->sortable()
                    ->searchable(),
                TextColumn::make('name')
                    ->label('نام پروژه')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('category.title')
                    ->label('نوع محصول / دسته')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('user.name')
                    ->label('کارفرما')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('producer.brand_name')
                    ->label('تولیدکننده')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('status')
                    ->label('وضعیت')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'pending' => 'warning',
                        'active' => 'success',
                        'approved' => 'success',
                        'rejected' => 'danger',
                        'edit' => 'warning',
                        'waiting' => 'gray',
                        'arbitration' => 'warning',
                        'unsigned' => 'gray',
                        'completed' => 'info',
                        'cancelled' => 'danger',
                        'expired' => 'gray',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string => self::getStatusOptions()[$state] ?? $state),
                IconColumn::make('sale_registration_enabled')
                    ->label('ثبت فروش')
                    ->boolean()
                    ->trueIcon('heroicon-o-check-circle')
                    ->falseIcon('heroicon-o-x-circle')
                    ->trueColor('success')
                    ->falseColor('danger'),
                TextColumn::make('budget')
                    ->label('بودجه')
                    ->formatStateUsing(fn ($state) => blank($state) ? null : \Illuminate\Support\Number::format((float) $state) . ' تومان')
                    ->sortable(),
                TextColumn::make('start_date')
                    ->label('تاریخ شروع')
                    ->jalaliDate('Y/m/d')
                    ->sortable(),
                TextColumn::make('deadline')
                    ->label('مهلت')
                    ->jalaliDate('Y/m/d')
                    ->sortable(),
                TextColumn::make('view_count')
                    ->label('بازدید')
                    ->sortable(),
                TextColumn::make('request_count')
                    ->label('درخواست')
                    ->sortable(),
                TextColumn::make('createdBy.name')
                    ->label('ایجادکننده')
                    ->hidden()
                    ->searchable()
                    ->sortable(),
                TextColumn::make('created_at')
                    ->label('تاریخ ایجاد')
                    ->jalaliDateTime('Y/m/d H:i')
                    ->sortable(),
            ])
            ->filters([
                TrashedFilter::make(),
                Filter::make('date_range')
                    ->label('بازه زمانی')
                    ->schema([
                        DatePicker::make('date_from')
                            ->label('از تاریخ')
                            ->jalali(),
                        DatePicker::make('date_to')
                            ->label('تا تاریخ')
                            ->jalali(),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        $from = $data['date_from'] ?? null;
                        $to = $data['date_to'] ?? null;
                        if (filled($from)) {
                            $query->whereDate('created_at', '>=', $from);
                        }
                        if (filled($to)) {
                            $query->whereDate('created_at', '<=', $to);
                        }
                        return $query;
                    })
                    ->indicateUsing(function (array $data): array {
                        $labels = [];
                        try {
                            if (! empty($data['date_from'])) {
                                $labels[] = 'از ' . \Morilog\Jalali\Jalalian::fromDateTime($data['date_from'])->format('Y/m/d');
                            }
                            if (! empty($data['date_to'])) {
                                $labels[] = 'تا ' . \Morilog\Jalali\Jalalian::fromDateTime($data['date_to'])->format('Y/m/d');
                            }
                        } catch (\Throwable) {
                            return [];
                        }
                        return $labels ? [\Filament\Tables\Filters\Indicator::make(implode(' ', $labels))->removeField('date_range')] : [];
                    }),
                SelectFilter::make('status')
                    ->label('وضعیت')
                    ->options(self::getStatusOptions()),
                SelectFilter::make('category_id')
                    ->label('نوع محصول / دسته')
                    ->relationship('category', 'title')
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::category($record))
                    ->searchable()
                    ->preload(),
                SelectFilter::make('user_id')
                    ->label('کارفرما')
                    ->relationship('user', 'name')
                    ->searchable(['name', 'cellphone'])
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::user($record))
                    ->preload(),
                SelectFilter::make('producer_id')
                    ->label('تولیدکننده')
                    ->relationship('producer', 'brand_name', function (Builder $query, ?string $search = null): Builder {
                        $query->with('user');

                        if (filled($search)) {
                            $query->where(function (Builder $q) use ($search): void {
                                $q->where('brand_name', 'like', "%{$search}%")
                                    ->orWhereHas('user', function (Builder $u) use ($search): void {
                                        $u->where('name', 'like', "%{$search}%")
                                            ->orWhere('national_code', 'like', "%{$search}%")
                                            ->orWhere('cellphone', 'like', "%{$search}%");
                                    });
                            });
                        }

                        return $query;
                    })
                    ->searchable(['brand_name'])
                    ->getOptionLabelFromRecordUsing(fn ($record): string => $record->brand_name . (
                        $record->relationLoaded('user') && $record->user
                            ? ' | ' . $record->user->name
                            : ''
                    ))
                    ->preload(),
                SelectFilter::make('sale_registration_enabled')
                    ->label('ثبت درخواست فروش')
                    ->options([
                        true => 'فعال',
                        false => 'غیرفعال',
                    ]),
                SelectFilter::make('province_id')
                    ->label('استان')
                    ->relationship('province', 'name')
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::generic($record, 'name', 'استان'))
                    ->searchable()
                    ->preload(),
                SelectFilter::make('county_id')
                    ->label('شهرستان')
                    ->relationship('county', 'name')
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::generic($record, 'name', 'شهر'))
                    ->searchable()
                    ->preload(),
            ])
            ->recordActions([
                EditAction::make(),
                Action::make('approve')
                    ->label('تأیید / فعال')
                    ->icon('heroicon-o-check')
                    ->color('success')
                    ->visible(fn (Project $record) => in_array($record->status, [
                        Project::STATUS_PENDING,
                        Project::STATUS_UNSIGNED,
                        Project::STATUS_WAITING,
                        Project::STATUS_EDIT,
                    ], true))
                    ->requiresConfirmation()
                    ->action(function (Project $record): void {
                        $record->update(['status' => Project::STATUS_ACTIVE]);
                        Notification::make()->title('پروژه فعال شد.')->success()->send();
                    }),
                Action::make('reject')
                    ->label('رد')
                    ->icon('heroicon-o-x-mark')
                    ->color('danger')
                    ->visible(fn (Project $record) => ! in_array($record->status, [
                        Project::STATUS_COMPLETED,
                        Project::STATUS_CANCELLED,
                        Project::STATUS_REJECTED,
                    ], true))
                    ->form([Textarea::make('reason')->label('دلیل رد')->rows(2)])
                    ->action(function (Project $record, array $data): void {
                        $record->update(['status' => Project::STATUS_REJECTED]);
                        Notification::make()->title('پروژه رد شد.')->danger()->send();
                    }),
                Action::make('toggle_sale')
                    ->label(fn (Project $record) => $record->sale_registration_enabled ? 'غیرفعال فروش' : 'فعال فروش')
                    ->icon('heroicon-o-currency-dollar')
                    ->color('gray')
                    ->action(function (Project $record): void {
                        $record->update([
                            'sale_registration_enabled' => ! $record->sale_registration_enabled,
                            'sale_deactivation_at' => $record->sale_registration_enabled ? now() : null,
                        ]);
                        Notification::make()
                            ->title($record->fresh()->sale_registration_enabled ? 'ثبت فروش فعال شد.' : 'ثبت فروش غیرفعال شد.')
                            ->success()
                            ->send();
                    }),
                Action::make('arbitration')
                    ->label('داوری')
                    ->icon('heroicon-o-scale')
                    ->color('warning')
                    ->visible(fn (Project $record) => $record->status === Project::STATUS_ACTIVE)
                    ->requiresConfirmation()
                    ->action(function (Project $record): void {
                        $record->update(['status' => Project::STATUS_ARBITRATION]);
                        Notification::make()->title('پروژه به داوری منتقل شد.')->warning()->send();
                    }),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make(),
                    ForceDeleteBulkAction::make(),
                    RestoreBulkAction::make(),
                ]),
            ]);
    }
}

