<?php

declare(strict_types=1);

namespace App\Filament\Resources\HeldPayments;

use App\Filament\Resources\HeldPayments\Pages\ListHeldPayments;
use App\Filament\Resources\HeldPayments\Pages\ViewHeldPayment;
use App\Filament\Resources\HeldPayments\Tables\HeldPaymentsTable;
use App\Models\HeldPayment;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use UnitEnum;

/**
 * Cobros que la cola offline no pudo aplicar con seguridad (PWA-001): llegaron
 * tarde, apuntan a un crédito que cambió, superan el saldo o los capturó otro
 * usuario del mismo teléfono. El admin los aprueba o los rechaza aquí.
 */
class HeldPaymentResource extends Resource
{
    protected static ?string $model = HeldPayment::class;

    protected static ?string $modelLabel = 'Cobro en revisión';

    protected static ?string $pluralModelLabel = 'Cobros en revisión';

    protected static ?string $navigationLabel = 'Cobros en revisión';

    protected static string|UnitEnum|null $navigationGroup = 'Gestión de Créditos';

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-inbox-stack';

    protected static ?int $navigationSort = 25;

    public static function getNavigationBadge(): ?string
    {
        /** @var Builder<HeldPayment> $query */
        $query = static::getEloquentQuery();
        $count = $query->pending()->count();

        return $count > 0 ? (string) $count : null;
    }

    public static function getNavigationBadgeColor(): ?string
    {
        return 'warning';
    }

    public static function table(Table $table): Table
    {
        return HeldPaymentsTable::configure($table);
    }

    public static function getPages(): array
    {
        return [
            'index' => ListHeldPayments::route('/'),
            'view' => ViewHeldPayment::route('/{record}'),
        ];
    }

    public static function getEloquentQuery(): Builder
    {
        $query = parent::getEloquentQuery()->with(['capturedBy', 'syncedBy', 'credit.client']);
        $user = Auth::user();

        if ($user && ! $user->isSuperAdmin()) {
            $query->where('company_id', $user->company_id);
        }

        // El super_admin ve todas las empresas: la columna "Empresa" es solo suya.
        if ($user?->isSuperAdmin()) {
            $query->with('company');
        }

        return $query;
    }

    public static function viewerIsSuperAdmin(): bool
    {
        return Auth::user()?->isSuperAdmin() ?? false;
    }

    /**
     * Quién cobró. Si el lote no reconoció al capturador, el retenido quedó a
     * nombre de quien lo SUBIÓ: ese nombre no se muestra como el del cobrador.
     * Null deja el placeholder "Usuario eliminado": si se borró el usuario, la FK
     * queda en null y no hay nada que confirmar (aunque el teléfono mandara un id).
     */
    public static function capturerLabel(HeldPayment $held): ?string
    {
        if ($held->captured_by_user_id === null) {
            return null;
        }

        if ($held->capturerIsConfirmed()) {
            return $held->capturedBy?->name;
        }

        $reported = $held->reportedCapturerId();

        return $reported !== null
            ? "No confirmado (el teléfono indicó #{$reported})"
            : 'No confirmado (el teléfono no indicó un usuario válido)';
    }

    /** En advertencia solo el "No confirmado"; el nombre y el placeholder, sin color. */
    public static function capturerColor(HeldPayment $held): ?string
    {
        return $held->captured_by_user_id !== null && ! $held->capturerIsConfirmed() ? 'warning' : null;
    }

    /** El crédito enlazado o, si no se pudo enlazar, el id que mandó el teléfono. */
    public static function creditLabel(HeldPayment $held): string
    {
        if ($held->credit_id !== null) {
            return "#{$held->credit_id}";
        }

        $reported = $held->reportedCreditId();

        return $reported !== null ? "No disponible (el teléfono indicó #{$reported})" : 'No disponible';
    }
}
