<?php

namespace App\Filament\Resources\Backtests\Schemas;

use App\Models\Backtest;
use Filament\Infolists\Components\IconEntry;
use Filament\Infolists\Components\KeyValueEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class BacktestInfolist
{
    public static function configure(Schema $schema): Schema
    {
        return $schema->components([
            Section::make('Run')->columns(3)->schema([
                TextEntry::make('model_version')->columnSpanFull(),
                TextEntry::make('directional_accuracy')
                    ->label('Accuracy')
                    ->state(fn (Backtest $record): string => $record->directional_accuracy === null
                        ? '—'
                        : round((float) $record->directional_accuracy, 1).'%'),
                TextEntry::make('mae_pence')
                    ->label('MAE')
                    ->state(fn (Backtest $record): string => $record->mae_pence === null
                        ? '—'
                        : number_format((float) $record->mae_pence, 2).'p'),
                IconEntry::make('leak_suspected')
                    ->label('Leak suspected')
                    ->boolean()
                    ->trueColor('danger'),
                TextEntry::make('train_start')->date('d M Y'),
                TextEntry::make('train_end')->date('d M Y'),
                TextEntry::make('eval_start')->date('d M Y'),
                TextEntry::make('eval_end')->date('d M Y'),
                TextEntry::make('ran_at')->dateTime('d M Y H:i'),
            ]),
            Section::make('Calibration table')
                ->description('Empirical hit rate per magnitude bin from the eval window.')
                ->schema([
                    KeyValueEntry::make('calibration_table')
                        ->hiddenLabel()
                        ->keyLabel('Magnitude bin')
                        ->valueLabel('Empirical hit rate')
                        ->state(fn (Backtest $record): array => collect($record->calibration_table ?? [])
                            ->mapWithKeys(fn ($value, $key) => [$key => round((float) $value * 100, 1).'%'])
                            ->all())
                        ->columnSpanFull(),
                ]),
            Section::make('Feature spec')->schema([
                KeyValueEntry::make('features_json')
                    ->hiddenLabel()
                    ->state(fn (Backtest $record): array => self::flattenForKeyValue($record->features_json))
                    ->columnSpanFull(),
            ]),
            Section::make('Coefficients')
                ->visible(fn (Backtest $record) => $record->coefficients_json !== null)
                ->collapsed()
                ->schema([
                    TextEntry::make('coefficients_json')
                        ->hiddenLabel()
                        ->state(fn (Backtest $record): string => json_encode(
                            $record->coefficients_json,
                            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
                        ) ?: '')
                        ->columnSpanFull(),
                ]),
        ]);
    }

    /**
     * KeyValueEntry expects a flat string-keyed map, so collapse nested arrays
     * into JSON strings rather than dropping them.
     *
     * @param  array<string, mixed>|null  $features
     * @return array<string, string>
     */
    protected static function flattenForKeyValue(?array $features): array
    {
        return collect($features ?? [])
            ->mapWithKeys(fn ($value, $key) => [
                (string) $key => is_scalar($value)
                    ? (string) $value
                    : (json_encode($value, JSON_UNESCAPED_SLASHES) ?: ''),
            ])
            ->all();
    }
}
