<?php

declare(strict_types=1);

namespace App\Filament\Resources\Expenses\Schemas;

use App\Enums\ExpenseCategory;
use Filament\Infolists\Components\IconEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Enums\TextSize;

class ExpenseInfolist
{
    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->components([

                // ══════════════════════════════════════════════════════════════
                // CABECERA FINANCIERA — Información principal del egreso
                // ══════════════════════════════════════════════════════════════

                Section::make('Detalle del egreso')
                    ->icon('heroicon-o-banknotes')
                    ->description(fn ($record) => filled($record->getCategoryDescription())
                        ? $record->getCategoryDescription()
                        : null
                    )
                    ->schema([

                        TextEntry::make('amount')
                            ->label('Monto')
                            ->icon('heroicon-o-currency-dollar')
                            ->money('COP', locale: 'es_CO')
                            ->size(TextSize::Large)
                            ->weight('bold')
                            ->color('danger'),

                        TextEntry::make('category')
                            ->label('Categoria')
                            ->badge()
                            ->formatStateUsing(fn ($state) => self::enumLabel($state, ExpenseCategory::class))
                            ->color(fn ($state) => self::enumColor($state, ExpenseCategory::class))
                            ->icon(fn ($state) => self::enumIcon($state, ExpenseCategory::class, 'heroicon-o-tag')),

                        TextEntry::make('operation_date')
                            ->label('Fecha de operacion')
                            ->icon('heroicon-o-calendar-days')
                            ->date('d M Y'),

                        TextEntry::make('method')
                            ->label('Metodo de pago')
                            ->badge()
                            ->formatStateUsing(fn ($state) => match ($state) {
                                'cash' => 'Efectivo',
                                'transfer' => 'Transferencia bancaria',
                                'card' => 'Tarjeta',
                                'mobile_money' => 'Billetera digital',
                                'other' => 'Otro',
                                default => $state ?? '—',
                            })
                            ->icon(fn ($state) => match ($state) {
                                'cash' => 'heroicon-o-banknotes',
                                'transfer' => 'heroicon-o-building-library',
                                'card' => 'heroicon-o-credit-card',
                                'mobile_money' => 'heroicon-o-device-phone-mobile',
                                default => 'heroicon-o-ellipsis-horizontal-circle',
                            }),

                        // Approval badge visible at a glance in the header only when required
                        TextEntry::make('approval_status')
                            ->label('Aprobacion')
                            ->badge()
                            ->formatStateUsing(fn ($state) => match ($state) {
                                'pending' => 'Pendiente',
                                'approved' => 'Aprobado',
                                'rejected' => 'Rechazado',
                                default => $state ?? '—',
                            })
                            ->color(fn ($state) => match ($state) {
                                'pending' => 'warning',
                                'approved' => 'success',
                                'rejected' => 'danger',
                                default => 'gray',
                            })
                            ->icon(fn ($state) => match ($state) {
                                'pending' => 'heroicon-o-clock',
                                'approved' => 'heroicon-o-check-circle',
                                'rejected' => 'heroicon-o-x-circle',
                                default => 'heroicon-o-question-mark-circle',
                            })
                            ->visible(fn ($record) => $record->requires_approval),

                        TextEntry::make('reference')
                            ->label('Referencia')
                            ->icon('heroicon-o-hashtag')
                            ->copyable()
                            ->copyMessage('Referencia copiada')
                            ->visible(fn ($record) => filled($record->reference)),

                    ])
                    ->columns(3),

                // ══════════════════════════════════════════════════════════════
                // ORIGEN — Trazabilidad y clasificacion contable
                // ══════════════════════════════════════════════════════════════

                Section::make('Origen y trazabilidad')
                    ->icon('heroicon-o-link')
                    ->description('Naturaleza contable del egreso y vinculacion con creditos u operaciones financieras')
                    ->schema([

                        TextEntry::make('operation_type_label')
                            ->label('Naturaleza del egreso')
                            ->getStateUsing(fn ($record) => match (true) {
                                $record->isCreditOperation() => 'Operacion de credito',
                                $record->isCapitalTransaction() => 'Transaccion de capital',
                                $record->isProvision() => 'Provision / Castigo',
                                default => 'Gasto operativo',
                            })
                            ->badge()
                            ->color(fn ($state) => match ($state) {
                                'Operacion de credito' => 'danger',
                                'Transaccion de capital' => 'purple',
                                'Provision / Castigo' => 'warning',
                                default => 'gray',
                            })
                            ->icon(fn ($state) => match ($state) {
                                'Operacion de credito' => 'heroicon-o-currency-dollar',
                                'Transaccion de capital' => 'heroicon-o-building-library',
                                'Provision / Castigo' => 'heroicon-o-exclamation-triangle',
                                default => 'heroicon-o-briefcase',
                            }),

                        TextEntry::make('credit.id')
                            ->label('Credito vinculado')
                            ->icon('heroicon-o-document-text')
                            ->prefix('#')
                            ->visible(fn ($record) => (bool) $record->credit_id),

                        TextEntry::make('credit.client.name')
                            ->label('Cliente')
                            ->icon('heroicon-o-user')
                            ->visible(fn ($record) => (bool) $record->credit_id),

                        TextEntry::make('financialOperation.operation_type')
                            ->label('Tipo de operacion financiera')
                            ->icon('heroicon-o-adjustments-horizontal')
                            ->badge()
                            ->formatStateUsing(fn ($state) => match ($state) {
                                'disbursement' => 'Desembolso',
                                'extension' => 'Extension',
                                'refinance' => 'Refinanciamiento',
                                'restructure' => 'Reestructuracion',
                                'renewal' => 'Renovacion',
                                default => $state ?? '—',
                            })
                            ->visible(fn ($record) => (bool) $record->financial_operation_id),

                    ])
                    ->columns(3)
                    ->collapsible(),

                // ══════════════════════════════════════════════════════════════
                // IMPACTO FINANCIERO — Los tres ejes contables del sistema
                // ══════════════════════════════════════════════════════════════

                Section::make('Impacto financiero')
                    ->icon('heroicon-o-scale')
                    ->description('Efecto de este egreso sobre caja, utilidades del periodo y capital de trabajo')
                    ->schema([

                        IconEntry::make('affects_cash')
                            ->label('Afecta caja')
                            ->boolean()
                            ->trueIcon('heroicon-o-banknotes')
                            ->falseIcon('heroicon-o-minus-circle')
                            ->trueColor('danger')
                            ->falseColor('gray'),

                        IconEntry::make('affects_profit')
                            ->label('Afecta utilidad')
                            ->boolean()
                            ->trueIcon('heroicon-o-arrow-trending-down')
                            ->falseIcon('heroicon-o-minus-circle')
                            ->trueColor('warning')
                            ->falseColor('gray'),

                        IconEntry::make('reduces_capital')
                            ->label('Reduce capital')
                            ->boolean()
                            ->trueIcon('heroicon-o-arrow-down-circle')
                            ->falseIcon('heroicon-o-minus-circle')
                            ->trueColor('purple')
                            ->falseColor('gray'),

                        TextEntry::make('financial_impact_summary')
                            ->label('Descripcion del impacto')
                            ->icon('heroicon-o-information-circle')
                            ->getStateUsing(fn ($record) => $record->getFinancialImpactSummary())
                            ->visible(fn ($record) => filled($record->getFinancialImpactSummary()))
                            ->columnSpanFull(),

                    ])
                    ->columns(3)
                    ->collapsible(),

                // ══════════════════════════════════════════════════════════════
                // APROBACION — Flujo de autorizacion del egreso
                // ══════════════════════════════════════════════════════════════

                Section::make('Flujo de aprobacion')
                    ->icon('heroicon-o-shield-check')
                    ->description('Este tipo de egreso requiere autorizacion antes de ser contabilizado')
                    ->schema([

                        TextEntry::make('approval_status')
                            ->label('Estado actual')
                            ->badge()
                            ->formatStateUsing(fn ($state) => match ($state) {
                                'pending' => 'Pendiente de aprobacion',
                                'approved' => 'Aprobado',
                                'rejected' => 'Rechazado',
                                default => $state ?? '—',
                            })
                            ->color(fn ($state) => match ($state) {
                                'pending' => 'warning',
                                'approved' => 'success',
                                'rejected' => 'danger',
                                default => 'gray',
                            })
                            ->icon(fn ($state) => match ($state) {
                                'pending' => 'heroicon-o-clock',
                                'approved' => 'heroicon-o-check-circle',
                                'rejected' => 'heroicon-o-x-circle',
                                default => 'heroicon-o-question-mark-circle',
                            }),

                        TextEntry::make('approvedBy.name')
                            ->label('Gestionado por')
                            ->icon('heroicon-o-user-circle')
                            ->default('—')
                            ->visible(fn ($record) => (bool) $record->approved_by_user_id),

                        TextEntry::make('approved_at')
                            ->label('Fecha de gestion')
                            ->icon('heroicon-o-calendar')
                            ->dateTime('d M Y, H:i')
                            ->visible(fn ($record) => (bool) $record->approved_at),

                        TextEntry::make('approval_notes')
                            ->label('Observaciones del aprobador')
                            ->icon('heroicon-o-chat-bubble-left-ellipsis')
                            ->visible(fn ($record) => filled($record->approval_notes))
                            ->columnSpanFull(),

                    ])
                    ->columns(3)
                    ->visible(fn ($record) => $record->requires_approval)
                    ->collapsible(),

                // ══════════════════════════════════════════════════════════════
                // BLOQUEO — Inmutabilidad del registro
                // (Solo visible cuando el registro está efectivamente bloqueado)
                // ══════════════════════════════════════════════════════════════

                Section::make('Registro bloqueado')
                    ->icon('heroicon-o-lock-closed')
                    ->description('Este egreso esta protegido contra modificaciones y eliminacion')
                    ->schema([

                        TextEntry::make('lock_reason')
                            ->label('Motivo del bloqueo')
                            ->icon('heroicon-o-information-circle')
                            ->default('Sin razon especificada'),

                        TextEntry::make('locked_at')
                            ->label('Bloqueado desde')
                            ->icon('heroicon-o-clock')
                            ->dateTime('d M Y, H:i'),

                    ])
                    ->columns(2)
                    ->visible(fn ($record) => $record->is_locked)
                    ->collapsible(),

                // ══════════════════════════════════════════════════════════════
                // NOTAS — Observaciones del usuario
                // ══════════════════════════════════════════════════════════════

                Section::make('Notas')
                    ->icon('heroicon-o-chat-bubble-left-ellipsis')
                    ->schema([
                        TextEntry::make('notes')
                            ->label('')
                            ->columnSpanFull(),
                    ])
                    ->visible(fn ($record) => filled($record->notes))
                    ->collapsible(),

                // ══════════════════════════════════════════════════════════════
                // METADATOS — Datos técnicos generados por el sistema
                // ══════════════════════════════════════════════════════════════

                Section::make('Informacion tecnica')
                    ->icon('heroicon-o-code-bracket')
                    ->description('Metadatos internos generados automaticamente por el sistema')
                    ->schema([

                        TextEntry::make('metadata_rendered')
                            ->label('')
                            ->getStateUsing(function ($record): string {
                                $metadata = $record->metadata ?? [];

                                if (empty($metadata)) {
                                    return 'Sin metadatos adicionales.';
                                }

                                $lines = [];

                                if (isset($metadata['installments']) && is_array($metadata['installments'])) {
                                    $lines[] = '**Cuotas afectadas:** #'
                                        .implode(', #', $metadata['installments']);
                                    unset($metadata['installments']);
                                }

                                foreach ($metadata as $key => $value) {
                                    $label = ucwords(str_replace('_', ' ', (string) $key));
                                    $val = is_array($value)
                                        ? json_encode($value, JSON_UNESCAPED_UNICODE)
                                        : (string) $value;
                                    $lines[] = "**{$label}:** {$val}";
                                }

                                return implode("\n\n", $lines);
                            })
                            ->markdown()
                            ->columnSpanFull(),

                    ])
                    ->visible(fn ($record) => ! empty($record->metadata))
                    ->collapsible()
                    ->collapsed(),

                // ══════════════════════════════════════════════════════════════
                // AUDITORIA — Trazabilidad del registro en el sistema
                // ══════════════════════════════════════════════════════════════

                Section::make('Auditoria')
                    ->icon('heroicon-o-clock')
                    ->schema([

                        TextEntry::make('id')
                            ->label('ID')
                            ->prefix('#')
                            ->copyable()
                            ->copyMessage('ID copiado'),

                        TextEntry::make('company.name')
                            ->label('Compania')
                            ->icon('heroicon-o-building-office'),

                        TextEntry::make('user.name')
                            ->label('Registrado por')
                            ->icon('heroicon-o-user-circle'),

                        TextEntry::make('collector.name')
                            ->label('Responsable')
                            ->icon('heroicon-o-user')
                            ->default('—'),

                        TextEntry::make('created_at')
                            ->label('Fecha de creacion')
                            ->dateTime('d M Y, H:i'),

                        TextEntry::make('updated_at')
                            ->label('Ultima modificacion')
                            ->dateTime('d M Y, H:i')
                            ->visible(fn ($record) => $record->updated_at?->ne($record->created_at)),

                    ])
                    ->columns(3)
                    ->collapsible()
                    ->collapsed(),

            ]);
    }

    // ══════════════════════════════════════════════════════════════════════════
    // ENUM HELPERS
    // Eliminan la repetición de ternarios en cada closure de badge/color/icon.
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Safely resolve an enum's label from a raw or enum-typed state.
     */
    private static function enumLabel(mixed $state, string $enumClass): string
    {
        if ($state instanceof $enumClass) {
            return $state->getLabel();
        }

        if (is_string($state)) {
            return $enumClass::tryFrom($state)?->getLabel() ?? $state;
        }

        return '—';
    }

    /**
     * Safely resolve an enum's Filament color from a raw or enum-typed state.
     */
    private static function enumColor(mixed $state, string $enumClass, string $fallback = 'gray'): string
    {
        if ($state instanceof $enumClass) {
            return $state->getColor();
        }

        if (is_string($state)) {
            return $enumClass::tryFrom($state)?->getColor() ?? $fallback;
        }

        return $fallback;
    }

    /**
     * Safely resolve an enum's Heroicon from a raw or enum-typed state.
     */
    private static function enumIcon(mixed $state, string $enumClass, string $fallback = 'heroicon-o-tag'): string
    {
        if ($state instanceof $enumClass) {
            return $state->getIcon();
        }

        if (is_string($state)) {
            return $enumClass::tryFrom($state)?->getIcon() ?? $fallback;
        }

        return $fallback;
    }
}
