<?php

declare(strict_types=1);

namespace App\Filament\Resources\WithdrawalRequests\Tables;

use App\Filament\Support\SelectOptionLabels;

use App\Models\WithdrawalRequest;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Actions\Action;
use Filament\Actions\ViewAction;
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 WithdrawalRequestsTable
{
    public static function configure(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn (Builder $query): Builder => $query->with(['user', 'bankCard']))
            ->defaultSort('created_at', 'desc')
            ->columns([
                TextColumn::make('id')->label('شناسه')->sortable(),
                TextColumn::make('user.getFilamentName')
                    ->label('درخواست‌کننده')
                    ->getStateUsing(fn (WithdrawalRequest $record) => $record->user?->getFilamentName())
                    ->searchable(['user.first_name', 'user.last_name', 'user.cellphone', 'user.national_code'])
                    ->sortable(),
                TextColumn::make('user.cellphone')->label('شماره همراه')->searchable()->toggleable(),
                TextColumn::make('user.national_code')->label('کد ملی')->searchable()->toggleable(),
                TextColumn::make('amount')
                    ->label('مبلغ')
                    ->formatStateUsing(fn ($state) => $state ? \Illuminate\Support\Number::format((float) $state) . ' تومان' : '-')
                    ->sortable(),
                TextColumn::make('shaba')->label('شماره شبا')->searchable()->toggleable(),
                TextColumn::make('bankCard.bank_name')->label('بانک')->toggleable()->toggledHiddenByDefault(),
                TextColumn::make('account_holder_name')->label('به نام')->toggleable(),
                TextColumn::make('wallet_balance_at_request')
                    ->label('موجودی کیف پول')
                    ->formatStateUsing(fn ($state) => $state !== null ? \Illuminate\Support\Number::format((float) $state) . ' تومان' : '-')
                    ->toggleable(),
                TextColumn::make('status')
                    ->label('وضعیت')
                    ->badge()
                    ->formatStateUsing(fn (string $state) => match ($state) {
                        WithdrawalRequest::STATUS_PENDING => 'در انتظار',
                        WithdrawalRequest::STATUS_APPROVED => 'تایید شده',
                        WithdrawalRequest::STATUS_REJECTED => 'رد شده',
                        default => $state,
                    })
                    ->color(fn (string $state) => match ($state) {
                        WithdrawalRequest::STATUS_PENDING => 'warning',
                        WithdrawalRequest::STATUS_APPROVED => 'success',
                        WithdrawalRequest::STATUS_REJECTED => 'danger',
                        default => 'gray',
                    })
                    ->sortable(),
                TextColumn::make('transfer_ref')->label('شناسه واریز')->toggleable()->toggledHiddenByDefault(),
                TextColumn::make('admin_note')->label('یادداشت ادمین')->limit(30)->toggleable()->toggledHiddenByDefault(),
                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([
                        WithdrawalRequest::STATUS_PENDING => 'در انتظار',
                        WithdrawalRequest::STATUS_APPROVED => 'تایید شده',
                        WithdrawalRequest::STATUS_REJECTED => 'رد شده',
                    ]),
                SelectFilter::make('user_id')
                    ->label('کاربر')
                    ->relationship('user', 'first_name', fn (Builder $q, array $data) => filled($data['search'] ?? null)
                        ? $q->where(function (Builder $b) use ($data) {
                            $state = $data['search'];
                            $b->where('first_name', 'like', "%{$state}%")
                                ->orWhere('last_name', 'like', "%{$state}%")
                                ->orWhere('cellphone', 'like', "%{$state}%")
                                ->orWhere('national_code', 'like', "%{$state}%")
                                ->orWhere('email', 'like', "%{$state}%");
                        })
                        : $q)
                    ->searchable(['first_name', 'last_name', 'cellphone', 'national_code', 'email'])
                    ->getOptionLabelFromRecordUsing(fn ($record) => SelectOptionLabels::user($record)),
            ])
            ->recordActions([
                ViewAction::make()
                    ->slideOver()
                    ->modalWidth('2xl')
                    ->fillForm(fn (WithdrawalRequest $record): array => [
                        'requester' => $record->user?->getFilamentName() . ' | ' . ($record->user?->cellphone ?: $record->user?->email ?? '-'),
                        'amount' => $record->amount ? \Illuminate\Support\Number::format((float) $record->amount) . ' تومان' : '-',
                        'shaba' => $record->shaba,
                        'account_holder_name' => $record->account_holder_name ?? '-',
                        'wallet_balance' => $record->wallet_balance_at_request !== null ? \Illuminate\Support\Number::format((float) $record->wallet_balance_at_request) . ' تومان' : '-',
                        'status' => match ($record->status) {
                            WithdrawalRequest::STATUS_PENDING => 'در انتظار',
                            WithdrawalRequest::STATUS_APPROVED => 'تایید شده',
                            WithdrawalRequest::STATUS_REJECTED => 'رد شده',
                            default => $record->status,
                        },
                        'transfer_ref' => $record->transfer_ref ?? '-',
                        'admin_note' => $record->admin_note ?? '-',
                        'created_at' => $record->created_at?->format('Y-m-d H:i'),
                    ])
                    ->form([
                        TextInput::make('requester')->label('درخواست‌کننده')->disabled(),
                        TextInput::make('amount')->label('مبلغ')->disabled(),
                        TextInput::make('shaba')->label('شماره شبا')->disabled(),
                        TextInput::make('account_holder_name')->label('به نام')->disabled(),
                        TextInput::make('wallet_balance')->label('موجودی کیف پول')->disabled(),
                        TextInput::make('status')->label('وضعیت')->disabled(),
                        TextInput::make('transfer_ref')->label('شناسه واریز')->disabled(),
                        Textarea::make('admin_note')->label('یادداشت ادمین')->disabled()->rows(2),
                        TextInput::make('created_at')->label('تاریخ/زمان')->disabled(),
                    ]),
                Action::make('approve')
                    ->label('تایید')
                    ->icon('heroicon-o-check')
                    ->color('success')
                    ->visible(fn (WithdrawalRequest $record) => $record->status === WithdrawalRequest::STATUS_PENDING)
                    ->form([
                        TextInput::make('transfer_ref')->label('شناسه واریز')->required()->maxLength(100),
                        Textarea::make('admin_note')->label('یادداشت')->rows(2),
                    ])
                    ->action(function (WithdrawalRequest $record, array $data): void {
                        $record->update([
                            'status' => WithdrawalRequest::STATUS_APPROVED,
                            'transfer_ref' => $data['transfer_ref'],
                            'admin_note' => $data['admin_note'] ?? null,
                            'processed_by' => \Illuminate\Support\Facades\Auth::id(),
                            'processed_at' => now(),
                        ]);
                        // مبلغ هنگام ثبت درخواست از کیف پول کسر (hold) شده است.
                        \Filament\Notifications\Notification::make()
                            ->title('درخواست برداشت تایید و شناسه واریز ثبت شد.')
                            ->success()
                            ->send();
                    }),
                Action::make('reject')
                    ->label('رد')
                    ->icon('heroicon-o-x-mark')
                    ->color('danger')
                    ->visible(fn (WithdrawalRequest $record) => $record->status === WithdrawalRequest::STATUS_PENDING)
                    ->form([
                        Textarea::make('admin_note')->label('دلیل رد')->required()->rows(3),
                    ])
                    ->action(function (WithdrawalRequest $record, array $data): void {
                        $user = $record->user;
                        if ($user) {
                            app(\App\Services\WalletService::class)->releaseWithdrawalHold(
                                $user,
                                (int) $record->amount,
                                'بازگشت مبلغ درخواست برداشت #' . $record->id,
                                ['withdrawal_request_id' => $record->id],
                            );
                        }

                        $record->update([
                            'status' => WithdrawalRequest::STATUS_REJECTED,
                            'admin_note' => $data['admin_note'],
                            'processed_by' => \Illuminate\Support\Facades\Auth::id(),
                            'processed_at' => now(),
                        ]);
                        \Filament\Notifications\Notification::make()
                            ->title('درخواست برداشت رد و مبلغ به کیف پول بازگشت.')
                            ->danger()
                            ->send();
                    }),
            ])
            ->defaultSort('created_at', 'desc');
    }
}
