<?php

declare(strict_types=1);

namespace App\Filament\Resources\ProjectRequests\Tables;

use App\Models\Project;
use App\Models\ProjectRequest;
use Filament\Actions\Action;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ProjectRequestsTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn ($query) => $query->with(['producer.user', 'createdBy', 'reviewedBy', 'project']))
            ->defaultSort('created_at', 'desc')
            ->columns([
                TextColumn::make('id')->label('#')->sortable(),
                TextColumn::make('title')->label('عنوان')->searchable()->limit(40),
                TextColumn::make('producer.brand_name')->label('تولیدکننده')->searchable()->placeholder('-'),
                TextColumn::make('status')
                    ->label('وضعیت')
                    ->badge()
                    ->formatStateUsing(fn (?string $state) => ProjectRequest::statusOptions()[$state] ?? $state)
                    ->color(fn (?string $state) => match ($state) {
                        ProjectRequest::STATUS_APPROVED => 'success',
                        ProjectRequest::STATUS_REJECTED => 'danger',
                        ProjectRequest::STATUS_EDIT => 'warning',
                        default => 'warning',
                    }),
                TextColumn::make('project.code')->label('پروژه ایجادشده')->placeholder('-'),
                TextColumn::make('created_at')->label('تاریخ')->jalaliDateTime('Y/m/d H:i')->sortable(),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->label('وضعیت')
                    ->options(ProjectRequest::statusOptions()),
            ])
            ->recordActions([
                ViewAction::make()->label('مشاهده'),
                Action::make('approve')
                    ->label('تأیید')
                    ->icon('heroicon-o-check')
                    ->color('success')
                    ->visible(fn (ProjectRequest $record) => $record->status === ProjectRequest::STATUS_WAITING)
                    ->form([
                        Toggle::make('create_project')
                            ->label('ایجاد پروژه از روی درخواست')
                            ->default(true),
                        Textarea::make('admin_note')->label('یادداشت (اختیاری)')->rows(2),
                    ])
                    ->action(function (ProjectRequest $record, array $data): void {
                        self::updateStatus($record, ProjectRequest::STATUS_APPROVED, $data['admin_note'] ?? null, (bool) ($data['create_project'] ?? true));
                        Notification::make()->title('درخواست تأیید شد.')->success()->send();
                    }),
                Action::make('needs_edit')
                    ->label('نیاز به ویرایش')
                    ->icon('heroicon-o-pencil-square')
                    ->color('warning')
                    ->visible(fn (ProjectRequest $record) => $record->status === ProjectRequest::STATUS_WAITING)
                    ->form([
                        Textarea::make('admin_note')->label('توضیحات برای تولیدکننده')->required()->rows(3),
                    ])
                    ->action(function (ProjectRequest $record, array $data): void {
                        self::updateStatus($record, ProjectRequest::STATUS_EDIT, $data['admin_note']);
                        Notification::make()->title('درخواست برای ویرایش برگشت داده شد.')->warning()->send();
                    }),
                Action::make('reject')
                    ->label('رد')
                    ->icon('heroicon-o-x-mark')
                    ->color('danger')
                    ->visible(fn (ProjectRequest $record) => in_array($record->status, [ProjectRequest::STATUS_WAITING, ProjectRequest::STATUS_EDIT], true))
                    ->form([
                        Textarea::make('admin_note')->label('دلیل رد')->required()->rows(3),
                    ])
                    ->action(function (ProjectRequest $record, array $data): void {
                        self::updateStatus($record, ProjectRequest::STATUS_REJECTED, $data['admin_note']);
                        Notification::make()->title('درخواست رد شد.')->danger()->send();
                    }),
            ]);
    }

    private static function updateStatus(ProjectRequest $record, string $status, ?string $adminNote, bool $createProject = false): void
    {
        DB::transaction(function () use ($record, $status, $adminNote, $createProject): void {
            $record->update([
                'status' => $status,
                'admin_note' => $adminNote,
                'reviewed_by' => Auth::id(),
                'reviewed_at' => now(),
            ]);

            if ($status === ProjectRequest::STATUS_APPROVED && $createProject && ! $record->project_id) {
                $payload = $record->payload ?? [];
                $project = Project::create([
                    'name' => $record->title,
                    'producer_id' => $record->producer_id,
                    'project_request_id' => $record->id,
                    'category_id' => $payload['category_id'] ?? null,
                    'breed_id' => $payload['breed_id'] ?? null,
                    'product_id' => $payload['product_id'] ?? null,
                    'quantity' => $payload['quantity'] ?? null,
                    'unit' => $payload['unit'] ?? null,
                    'unit_price' => $payload['unit_price'] ?? null,
                    'desc' => $payload['desc'] ?? ($payload['product_name'] ?? null),
                    'estimated_profit' => $payload['estimated_profit'] ?? null,
                    'province_id' => $payload['province_id'] ?? null,
                    'county_id' => $payload['county_id'] ?? null,
                    'start_date' => $payload['start_date'] ?? null,
                    'end_date' => $payload['end_date'] ?? null,
                    'status' => Project::STATUS_PENDING,
                    'created_by' => Auth::id(),
                    'updated_by' => Auth::id(),
                ]);
                $record->update(['project_id' => $project->id]);
            }
        });
    }
}
