<?php

declare(strict_types=1);

namespace App\Filament\Resources\Invoices\Tables;

use App\Filament\Support\SelectOptionLabels;

use App\Models\Invoice;
use App\Services\InvoiceService;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class InvoicesTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn (Builder $query): Builder => $query->with(['project', 'user']))
            ->columns([
                TextColumn::make('number')->label('شماره فاکتور')->searchable()->sortable(),
                TextColumn::make('title')->label('نام تراکنش')->searchable()->toggleable(),
                TextColumn::make('project.name')->label('پروژه')->searchable()->sortable(),
                TextColumn::make('project.code')->label('کد پروژه')->sortable(),
                TextColumn::make('user.getFilamentName')->label('کاربر')->getStateUsing(fn (Invoice $record) => $record->user?->getFilamentName())->toggleable(),
                TextColumn::make('type')->label('نوع')->formatStateUsing(fn (string $state) => $state === Invoice::TYPE_INCOME ? 'درآمد' : 'هزینه')->badge()->color(fn (string $state) => $state === Invoice::TYPE_INCOME ? 'success' : 'danger'),
                TextColumn::make('status')->label('وضعیت')->badge()->formatStateUsing(fn (string $state) => match ($state) {
                    Invoice::STATUS_DRAFT => 'پیش‌نویس',
                    Invoice::STATUS_PENDING => 'در انتظار',
                    Invoice::STATUS_PAID => 'پرداخت شده',
                    Invoice::STATUS_UNPAID => 'پرداخت نشده',
                    Invoice::STATUS_APPROVED => 'تایید',
                    Invoice::STATUS_REJECTED => 'رد',
                    Invoice::STATUS_NEEDS_EDIT => 'نیاز به ویرایش',
                    default => $state,
                })->color(fn (string $state) => match ($state) {
                    Invoice::STATUS_PAID, Invoice::STATUS_APPROVED => 'success',
                    Invoice::STATUS_REJECTED => 'danger',
                    Invoice::STATUS_PENDING, Invoice::STATUS_UNPAID => 'warning',
                    default => 'gray',
                }),
                TextColumn::make('total')->label('جمع کل')->formatStateUsing(fn ($state) => $state ? \Illuminate\Support\Number::format((float) $state) . ' تومان' : '-')->sortable(),
                TextColumn::make('issued_at')->label('تاریخ صدور')->jalaliDate('Y/m/d')->sortable(),
                TextColumn::make('due_at')->label('سررسید')->jalaliDate('Y/m/d')->sortable(),
                TextColumn::make('created_at')->label('ایجاد')->jalaliDateTime('Y/m/d H:i')->sortable(),
            ])
            ->filters([
                Filter::make('date_range')
                    ->label('بازه زمانی')
                    ->schema([
                        DatePicker::make('date_from')->label('از تاریخ')->jalali(),
                        DatePicker::make('date_to')->label('تا تاریخ')->jalali(),
                    ])
                    ->query(function (Builder $q, array $data): Builder {
                        if (filled($data['date_from'] ?? null)) {
                            $q->whereDate('created_at', '>=', $data['date_from']);
                        }
                        if (filled($data['date_to'] ?? null)) {
                            $q->whereDate('created_at', '<=', $data['date_to']);
                        }

                        return $q;
                    }),
                SelectFilter::make('status')
                    ->label('وضعیت')
                    ->options([
                        Invoice::STATUS_DRAFT => 'پیش‌نویس',
                        Invoice::STATUS_PENDING => 'در انتظار',
                        Invoice::STATUS_PAID => 'پرداخت شده',
                        Invoice::STATUS_UNPAID => 'پرداخت نشده',
                        Invoice::STATUS_APPROVED => 'تایید',
                        Invoice::STATUS_REJECTED => 'رد',
                        Invoice::STATUS_NEEDS_EDIT => 'نیاز به ویرایش',
                    ]),
                SelectFilter::make('type')
                    ->label('نوع تراکنش')
                    ->options([
                        Invoice::TYPE_INCOME => 'درآمد',
                        Invoice::TYPE_EXPENSE => 'هزینه',
                    ]),
                SelectFilter::make('project_id')
                    ->label('پروژه')
                    ->relationship('project', 'name')
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::project($record))
                    ->searchable()
                    ->preload(),
            ])
            ->recordActions([
                ViewAction::make()
                    ->slideOver()
                    ->modalWidth('3xl')
                    ->fillForm(fn (Invoice $record): array => [
                        'number' => $record->number,
                        'title' => $record->title,
                        'type' => $record->type === Invoice::TYPE_INCOME ? 'درآمد' : 'هزینه',
                        'status' => $record->status,
                        'total' => $record->total ? \Illuminate\Support\Number::format((float) $record->total) . ' تومان' : '-',
                        'project' => ($record->project?->name ?? '-') . ' / ' . ($record->project?->code ?? '-'),
                        'user' => $record->user?->getFilamentName(),
                        'counterparty' => $record->counterparty_name,
                        'description' => $record->description,
                        'admin_reason' => $record->admin_reason,
                    ])
                    ->form([
                        TextInput::make('number')->label('شماره')->disabled(),
                        TextInput::make('title')->label('نام تراکنش')->disabled(),
                        TextInput::make('type')->label('نوع')->disabled(),
                        TextInput::make('status')->label('وضعیت')->disabled(),
                        TextInput::make('total')->label('مبلغ')->disabled(),
                        TextInput::make('project')->label('پروژه')->disabled(),
                        TextInput::make('user')->label('کاربر')->disabled(),
                        TextInput::make('counterparty')->label('واسطه')->disabled(),
                        Textarea::make('description')->label('شرح')->disabled()->rows(2),
                        Textarea::make('admin_reason')->label('یادداشت')->disabled()->rows(2),
                    ]),
                EditAction::make(),
                Action::make('approve')
                    ->label('تایید')
                    ->icon('heroicon-o-check')
                    ->color('success')
                    ->visible(fn (Invoice $record) => $record->status === Invoice::STATUS_PENDING)
                    ->requiresConfirmation()
                    ->action(function (Invoice $record): void {
                        app(InvoiceService::class)->approve($record);
                        Notification::make()->title('فاکتور تایید شد.')->success()->send();
                    }),
                Action::make('reject')
                    ->label('رد')
                    ->icon('heroicon-o-x-mark')
                    ->color('danger')
                    ->visible(fn (Invoice $record) => $record->status === Invoice::STATUS_PENDING)
                    ->form([
                        Textarea::make('admin_reason')->label('دلیل رد')->required()->rows(3),
                    ])
                    ->action(function (Invoice $record, array $data): void {
                        app(InvoiceService::class)->reject($record, $data['admin_reason']);
                        Notification::make()->title('فاکتور رد شد.')->danger()->send();
                    }),
                Action::make('needs_edit')
                    ->label('نیاز به ویرایش')
                    ->icon('heroicon-o-pencil-square')
                    ->color('warning')
                    ->visible(fn (Invoice $record) => $record->status === Invoice::STATUS_PENDING)
                    ->form([
                        Textarea::make('admin_reason')->label('دلیل ویرایش')->required()->rows(3),
                    ])
                    ->action(function (Invoice $record, array $data): void {
                        app(InvoiceService::class)->needsEdit($record, $data['admin_reason']);
                        Notification::make()->title('فاکتور برای ویرایش ارجاع شد.')->warning()->send();
                    }),
            ])
            ->defaultSort('created_at', 'desc');
    }
}
