<?php

declare(strict_types=1);

namespace App\Filament\Widgets\Collector;

use App\Filament\Resources\Payments\PaymentResource;
use App\Models\Credit;
use App\Models\Installment;
use Filament\Actions\Action;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;

class CollectorDueInstallmentsTable extends BaseWidget
{
    protected static ?string $heading = 'Cuotas por Cobrar';

    protected static ?string $description = 'Cuotas que vencen hoy y vencidas, ordenadas por prioridad';

    protected static ?int $sort = 2;

    protected int|string|array $columnSpan = 'full';

    protected ?string $pollingInterval = '60s';

    public static function canView(): bool
    {
        $user = Auth::user();

        return $user && $user->hasRole('collector') && ! $user->isSuperAdmin();
    }

    protected function getTableQuery(): Builder
    {
        $user = Auth::user();
        $today = Carbon::today();

        return Installment::query()
            ->where('company_id', $user->company_id)
            ->whereHas('credit', function (Builder $q) use ($user) {
                $q->leafCredits()
                    ->where('collector_user_id', $user->id)
                    ->whereIn('status', Credit::ACTIVE_STATUSES);
            })
            ->where('status', '!=', Installment::STATUS_PAID)
            ->where('due_date', '<=', $today->toDateString())
            ->with('credit.client:id,name')
            ->orderBy('due_date');
    }

    public function table(Table $table): Table
    {
        $today = Carbon::today();

        return $table
            ->defaultPaginationPageOption(10)
            ->paginated([10, 25, 50])
            ->columns([
                TextColumn::make('credit.client.name')
                    ->label('Cliente')
                    ->searchable()
                    ->sortable(),

                TextColumn::make('installment_number')
                    ->label('Cuota #')
                    ->badge()
                    ->color('gray')
                    ->alignCenter(),

                TextColumn::make('due_date')
                    ->label('Vence')
                    ->date('d/m/Y')
                    ->sortable()
                    ->color(fn (Installment $record) => $record->due_date->lt($today) ? 'danger' : 'warning'
                    )
                    ->icon(fn (Installment $record) => $record->due_date->lt($today) ? 'heroicon-m-exclamation-triangle' : null
                    ),

                // Ver nota en InstallmentsDueTodayTable: `principal_balance_after` es el saldo de
                // capital tras la cuota, no lo que falta por cobrar de ella.
                TextColumn::make('remaining_amount')
                    ->label('Monto Pendiente')
                    ->money('COP', locale: 'es_CO')
                    ->alignEnd()
                    ->sortable(query: fn (Builder $query, string $direction): Builder => $query->orderByRaw(
                        'GREATEST(0, total_amount - amount_paid) '.($direction === 'desc' ? 'desc' : 'asc')
                    )),

                TextColumn::make('status')
                    ->label('Estado')
                    ->badge()
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        Installment::STATUS_PENDING => 'Pendiente',
                        Installment::STATUS_PARTIAL_PAID => 'Parcial',
                        Installment::STATUS_OVERDUE => 'Vencida',
                        default => ucfirst($state),
                    })
                    ->color(fn (string $state): string => match ($state) {
                        Installment::STATUS_PENDING => 'warning',
                        Installment::STATUS_PARTIAL_PAID => 'info',
                        Installment::STATUS_OVERDUE => 'danger',
                        default => 'gray',
                    }),
            ])
            ->actions([
                Action::make('registrar_pago')
                    ->label('Registrar Pago')
                    ->icon('heroicon-o-banknotes')
                    ->color('success')
                    ->url(fn (Installment $record) => PaymentResource::getUrl('create', ['credit_id' => $record->credit_id])
                    )
                    ->openUrlInNewTab(),
            ])
            ->emptyStateHeading('Sin cuotas pendientes')
            ->emptyStateDescription('No hay cuotas vencidas ni por cobrar hoy.')
            ->emptyStateIcon('heroicon-o-check-circle');
    }
}
