<?php

declare(strict_types=1);

namespace App\Filament\Widgets\Supervisor;

use App\Models\Installment;
use App\Services\CollectorVisibilityResolver;
use Carbon\Carbon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;

/**
 * Tabla de cuotas vencidas prioritarias.
 *
 * Muestra las cuotas con más días de mora para gestión prioritaria.
 */
class OverdueInstallmentsTable extends BaseWidget
{
    protected static ?string $heading = 'Cuotas Vencidas (Prioritarias)';

    protected static ?int $sort = 6;

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

    /**
     * Solo visible para Supervisores.
     */
    public static function canView(): bool
    {
        $user = Auth::user();

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

    public function table(Table $table): Table
    {
        $user = Auth::user();
        $companyId = $user->company_id;
        $today = Carbon::today();

        // Visibilidad supervisor→cobrador (#71): un supervisor asignado solo ve las
        // cuotas de su equipo; con sees_all_collectors ve toda la empresa.
        $collectorIds = app(CollectorVisibilityResolver::class)->visibleCollectorIds($user);

        return $table
            ->query(
                Installment::query()
                    ->where('company_id', $companyId)
                    ->whereHas('credit', function (Builder $q) use ($collectorIds) {
                        $q->leafCredits()
                            ->whereIn('status', ['active', 'delayed', 'overdue']);
                        if ($collectorIds !== null) {
                            $q->whereIn('collector_user_id', $collectorIds);
                        }
                    })
                    ->where('due_date', '<', $today->toDateString())
                    ->where('status', '!=', 'paid')
                    ->with(['credit.client', 'credit.collector'])
            )
            ->columns([
                TextColumn::make('days_overdue')
                    ->label('Días Mora')
                    ->getStateUsing(function (Installment $record) use ($today) {
                        return $record->due_date->diffInDays($today);
                    })
                    ->badge()
                    ->color(fn (int $state): string => match (true) {
                        $state > 60 => 'danger',
                        $state > 30 => 'warning',
                        $state > 7 => 'info',
                        default => 'gray',
                    })
                    ->sortable(query: function (Builder $query, string $direction): Builder {
                        return $query->orderBy('due_date', $direction === 'desc' ? 'asc' : 'desc');
                    }),

                TextColumn::make('credit.client.name')
                    ->label('Cliente')
                    ->searchable()
                    ->sortable()
                    ->limit(20),

                TextColumn::make('credit.collector.name')
                    ->label('Collector')
                    ->default('Sin asignar')
                    ->badge()
                    ->color('gray'),

                TextColumn::make('due_date')
                    ->label('Vencimiento')
                    ->date('d/m/Y')
                    ->sortable(),

                // 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')
                    ->money('COP')
                    ->sortable(query: fn (Builder $query, string $direction): Builder => $query->orderByRaw(
                        'GREATEST(0, total_amount - amount_paid) '.($direction === 'desc' ? 'desc' : 'asc')
                    ))
                    ->color('danger'),

                TextColumn::make('installment_number')
                    ->label('Cuota')
                    ->formatStateUsing(fn (int $state): string => "#{$state}"),
            ])
            ->filters([
                SelectFilter::make('collector')
                    ->label('Collector')
                    ->relationship('credit.collector', 'name')
                    ->preload()
                    ->searchable(),
            ])
            ->defaultSort('due_date', 'asc')
            ->paginated([10, 25, 50])
            ->emptyStateHeading('Sin cuotas vencidas')
            ->emptyStateDescription('No hay cuotas vencidas pendientes de cobro.')
            ->emptyStateIcon('heroicon-o-check-circle');
    }
}
