<?php

namespace App\Filament\Support;

use App\Services\CurrentContext;
use Closure;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Support\Enums\TextSize;

/**
 * The recurring blue/green/red financial triad — Payable / Paid / Balance —
 * as one reusable infolist section. Money must read from shape and colour:
 * blue for the gross figure, green for what's been settled, red for what is
 * still owed. Used on Invoice, Sales Order, Customer, Supplier and Transaction
 * view pages.
 *
 * Each value is a closure receiving the record, so the same section works
 * against any model:
 *
 *   MoneyTriad::make(
 *       payable: fn (Invoice $record) => (float) $record->net_total,
 *       paid: fn (Invoice $record) => (float) $record->paid_amount,
 *       balance: fn (Invoice $record) => (float) $record->balance,
 *   );
 */
class MoneyTriad
{
    public static function make(
        Closure $payable,
        Closure $paid,
        Closure $balance,
        string $payableLabel = 'Payable',
        string $paidLabel = 'Paid',
        string $balanceLabel = 'Balance',
    ): Section {
        $money = fn (): string => app(CurrentContext::class)->currencyCode();

        return Section::make()
            ->columns(3)
            ->schema([
                TextEntry::make('triad_payable')
                    ->label($payableLabel)
                    ->state($payable)
                    ->money($money)
                    ->color('primary')
                    ->size(TextSize::Large),
                TextEntry::make('triad_paid')
                    ->label($paidLabel)
                    ->state($paid)
                    ->money($money)
                    ->color('success')
                    ->size(TextSize::Large),
                TextEntry::make('triad_balance')
                    ->label($balanceLabel)
                    ->state($balance)
                    ->money($money)
                    ->color(fn ($record): string => (float) ($balance)($record) > 0 ? 'danger' : 'success')
                    ->size(TextSize::Large),
            ]);
    }
}