<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\Payments\PaymentResource;
use App\Models\Credit;
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;
use Illuminate\Support\Number;

class MoraCreditsTable extends BaseWidget
{
    protected static ?string $heading = 'Cartera en Mora (Créditos Prioritarios)';

    protected static ?int $sort = 3;

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

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

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

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

        // IMPORTANTE: Excluir créditos padre (con hijos derivados)
        $query = Credit::query()
            ->whereIn('status', ['delayed', 'overdue'])
            ->whereDoesntHave('children') // Excluir créditos padre
            ->where('company_id', $user->company_id)
            ->with([
                'client:id,name',
                'installments',
                'payments' => fn ($q) => $q->where('voided', 0),
            ]);

        // Collector: solo ve créditos asignados a él
        if ($user->hasRole('collector')) {
            $query->where('collector_user_id', $user->id);
        }

        return $query;
    }

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

        return $table
            ->defaultPaginationPageOption(5)
            ->paginated([5, 10, 25])
            ->columns([

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

                TextColumn::make('amount')
                    ->label('Principal')
                    ->money('COP', locale: 'es_CO')
                    ->alignEnd(),

                // Cuota vencida más antigua
                TextColumn::make('oldest_overdue_installment')
                    ->label('Cuota Vencida')
                    ->getStateUsing(function (Credit $credit) use ($today) {
                        $inst = $credit->installments
                            ->filter(fn ($i) => Carbon::parse($i->due_date)->lt($today) &&
                                $i->amount_paid < $i->total_amount
                            )
                            ->sortBy('due_date')
                            ->first();

                        return $inst
                            ? Number::currency($inst->total_amount, 'COP', locale: 'es_CO')
                            : '—';
                    })
                    ->alignEnd(),

                // Días de mora
                TextColumn::make('days_overdue')
                    ->label('Días en Mora')
                    ->badge()
                    ->color('danger')
                    ->getStateUsing(function (Credit $credit) use ($today) {
                        $inst = $credit->installments
                            ->filter(fn ($i) => Carbon::parse($i->due_date)->lt($today) &&
                                $i->amount_paid < $i->total_amount
                            )
                            ->sortBy('due_date')
                            ->first();

                        return $inst
                            ? Carbon::parse($inst->due_date)->diffInDays($today)
                            : 0;
                    }),

                // Saldo vencido real
                TextColumn::make('overdue_balance')
                    ->label('Saldo Vencido')
                    ->money('COP', locale: 'es_CO')
                    ->alignEnd()
                    ->getStateUsing(fn (Credit $credit) => $credit->installments->sum(
                        fn ($i) => Carbon::parse($i->due_date)->lt(Carbon::today())
                                ? max(0, $i->total_amount - $i->amount_paid)
                                : 0
                    )
                    ),

                // Último pago real
                TextColumn::make('last_payment')
                    ->label('Último Abono')
                    ->getStateUsing(function (Credit $credit) {
                        $latest = $credit->payments->sortByDesc('payment_date')->first();

                        return $latest
                            ? Carbon::parse($latest->payment_date)->diffForHumans()
                            : 'N/A';
                    })
                    ->color(fn ($state) => $state === 'N/A' ? 'danger' : 'info'),

                TextColumn::make('status')
                    ->label('Estado Crédito')
                    ->badge()
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        'active' => 'Activo',
                        'delayed' => 'En mora',
                        'overdue' => 'Vencido',
                        default => 'Desconocido',
                    })
                    ->color(fn (string $state): string => match ($state) {
                        'active' => 'info',
                        'delayed' => 'warning',
                        'overdue' => 'danger',
                        default => 'gray',
                    }),

            ])
            ->actions([
                Action::make('abonar')
                    ->label('Registrar Pago')
                    ->icon('heroicon-o-banknotes')
                    ->color('success')
                    ->url(fn (Credit $record) => PaymentResource::getUrl('create', ['credit_id' => $record->id])
                    )
                    ->openUrlInNewTab(),
            ])
            ->emptyStateHeading('Excelente 🎉 No hay créditos en mora')
            ->emptyStateIcon('heroicon-o-check-circle');
    }
}
