<?php

namespace App\Filament\Resources\PaymentAuditLog\Schemas;

use App\Enums\PaymentAuditEvent;
use App\Filament\Resources\Credits\CreditResource;
use App\Filament\Resources\Payments\PaymentResource;
use App\Services\Audit\AuditPresenter;
use App\Support\Format;
use Filament\Infolists\Components\TextEntry;
use Filament\Infolists\Components\ViewEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

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

            // ═════════════════════════════════════════════════════════
            // EVENTO — Qué pasó, quién, cuándo
            // ═════════════════════════════════════════════════════════
            Section::make('Evento')
                ->schema([
                    TextEntry::make('action')
                        ->label('Acción')
                        ->badge()
                        ->formatStateUsing(fn (string $state): string => PaymentAuditEvent::tryFrom($state)?->label() ?? ucfirst($state)
                        )
                        ->color(fn (string $state): string => PaymentAuditEvent::tryFrom($state)?->color() ?? 'gray'
                        )
                        ->icon(fn (string $state): ?string => PaymentAuditEvent::tryFrom($state)?->icon()
                        ),

                    TextEntry::make('action')
                        ->label('Resumen')
                        ->formatStateUsing(function (string $state, $record): string {
                            $event = PaymentAuditEvent::tryFrom($state);

                            return $event?->summary([
                                'amount' => $record->amount,
                                'credit_id' => $record->credit_id,
                                'installment_id' => $record->installment_id,
                            ]) ?? $state;
                        })
                        ->hiddenLabel()
                        ->columnSpanFull(),

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

                    TextEntry::make('amount')
                        ->label('Monto')
                        ->icon('heroicon-o-banknotes')
                        ->formatStateUsing(fn ($state) => Format::money($state)),

                    TextEntry::make('created_at')
                        ->label('Fecha')
                        ->icon('heroicon-o-clock')
                        ->dateTime('d/m/Y H:i'),
                ])
                ->columns(3),

            // ═════════════════════════════════════════════════════════
            // CONTEXTO — Enlaces a entidades relacionadas
            // ═════════════════════════════════════════════════════════
            Section::make('Contexto')
                ->schema([
                    TextEntry::make('payment.id')
                        ->label('Pago')
                        ->icon('heroicon-o-banknotes')
                        ->url(fn ($record) => $record->payment_id
                            ? PaymentResource::getUrl('view', ['record' => $record->payment_id])
                            : null
                        )
                        ->visible(fn ($record) => $record->payment_id !== null),

                    TextEntry::make('credit.id')
                        ->label('Crédito')
                        ->icon('heroicon-o-document-text')
                        ->url(fn ($record) => $record->credit_id
                            ? CreditResource::getUrl('view', ['record' => $record->credit_id])
                            : null
                        )
                        ->visible(fn ($record) => $record->credit_id !== null),

                    TextEntry::make('installment_id')
                        ->label('Cuota')
                        ->icon('heroicon-o-calendar-days')
                        ->visible(fn ($record) => $record->installment_id !== null),
                ])
                ->columns(3),

            // ═════════════════════════════════════════════════════════
            // CAMPOS MODIFICADOS — Diff before/after traducido
            // ═════════════════════════════════════════════════════════
            Section::make('Campos modificados')
                ->schema([
                    ViewEntry::make('changes_table')
                        ->view('filament.infolists.components.audit-changes-table')
                        ->viewData([
                            'changesResolver' => fn ($record) => AuditPresenter::computeChanges(
                                is_array($record->previous_data) ? $record->previous_data : null,
                                is_array($record->new_data) ? $record->new_data : null,
                            ),
                        ])
                        ->columnSpanFull(),
                ])
                ->visible(fn ($record) => ! empty($record->previous_data) || ! empty($record->new_data)),

            // ═════════════════════════════════════════════════════════
            // DATOS TÉCNICOS — JSON original, colapsado
            // ═════════════════════════════════════════════════════════
            Section::make('Datos técnicos — Estado previo')
                ->schema([
                    TextEntry::make('previous_data')
                        ->label('JSON original')
                        ->formatStateUsing(fn ($state) => self::prettyJson($state))
                        ->columnSpanFull()
                        ->copyable()
                        ->copyMessage('JSON copiado al portapapeles'),
                ])
                ->collapsible()
                ->collapsed()
                ->visible(fn ($record) => ! empty($record->previous_data)),

            Section::make('Datos técnicos — Estado posterior')
                ->schema([
                    TextEntry::make('new_data')
                        ->label('JSON original')
                        ->formatStateUsing(fn ($state) => self::prettyJson($state))
                        ->columnSpanFull()
                        ->copyable()
                        ->copyMessage('JSON copiado al portapapeles'),
                ])
                ->collapsible()
                ->collapsed()
                ->visible(fn ($record) => ! empty($record->new_data)),
        ]);
    }

    protected static function prettyJson(mixed $state): string
    {
        if (! $state) {
            return '';
        }

        if (is_string($state)) {
            return $state;
        }

        return json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ?: '';
    }
}
