<?php

namespace App\Support;

/**
 * Mirrors inferDebtInput from bugets-smart-money/src/lib/smart-form.ts
 *
 * @return array{
 *     icon?: string,
 *     type?: string,
 *     interestRate?: float,
 *     dueDay?: int,
 *     suggestions: list<array{id: string, label: string, detail?: string, tone?: string}>
 * }
 */
final class DebtInference
{
    /** @var list<array{match: list<string>, icon: string, type: string, rate: float, dueDay: int}> */
    private const DEBT_RULEBOOK = [
        ['match' => ['credit card', 'visa', 'mastercard', 'amex'], 'icon' => '💳', 'type' => 'credit_card', 'rate' => 19.9, 'dueDay' => 15],
        ['match' => ['student', 'tuition'], 'icon' => '🎓', 'type' => 'loan', 'rate' => 4.5, 'dueDay' => 1],
        ['match' => ['car loan', 'auto loan', 'vehicle finance', 'car', 'auto'], 'icon' => '🚗', 'type' => 'loan', 'rate' => 6.2, 'dueDay' => 5],
        ['match' => ['phone', 'klarna', 'afterpay', 'bnpl'], 'icon' => '📱', 'type' => 'bnpl', 'rate' => 0.0, 'dueDay' => 20],
        ['match' => ['mortgage', 'home loan', 'house loan', 'refinance', 'hipoteca'], 'icon' => '🏠', 'type' => 'mortgage', 'rate' => 3.8, 'dueDay' => 1],
        ['match' => ['personal loan', 'signature loan', 'consumer loan'], 'icon' => '💰', 'type' => 'personal', 'rate' => 11.9, 'dueDay' => 10],
    ];

    /**
     * @return array<string, mixed>
     */
    public static function infer(string $name, string $rate, array $history = []): array
    {
        $input = mb_strtolower(trim($name));
        $suggestions = [];
        $result = ['suggestions' => $suggestions];

        foreach (self::DEBT_RULEBOOK as $rule) {
            if (! FinancialKeywordMatch::containsAny($name, $rule['match'])) {
                continue;
            }
            $result['icon'] = $rule['icon'];
            $result['type'] = $rule['type'];
            $result['dueDay'] = $rule['dueDay'];
            if ($rate === '' || $rate === '0') {
                $result['interestRate'] = $rule['rate'];
            }
            $typeLabel = str_replace('_', ' ', $rule['type']);
            $suggestions[] = [
                'id' => 'debt-'.$rule['type'],
                'label' => 'Detected '.$typeLabel,
                'detail' => 'Prefilled icon, due day, and common APR',
                'tone' => $rule['type'] === 'credit_card' ? 'warning' : 'positive',
            ];
            $result['suggestions'] = $suggestions;
            break;
        }

        $apr = (float) ($rate !== '' ? $rate : ($result['interestRate'] ?? 0));
        if ($apr >= 15) {
            $suggestions[] = [
                'id' => 'priority',
                'label' => 'High APR debt',
                'detail' => 'Should likely be prioritized in payoff strategy',
                'tone' => 'warning',
            ];
        } elseif ($apr === 0.0) {
            $suggestions[] = [
                'id' => 'zero-apr',
                'label' => '0% APR detected',
                'detail' => 'Minimum payments may be enough for now',
                'tone' => 'positive',
            ];
        }

        // Learn probable debt settings from similar records.
        $nameTokens = array_values(array_filter(preg_split('/[^a-z0-9]+/i', $input ?: '')));
        $bestScore = 0;
        $bestRow = null;
        foreach ($history as $row) {
            if (! is_array($row)) {
                continue;
            }
            $rowName = mb_strtolower((string) ($row['name'] ?? ''));
            if ($rowName === '') {
                continue;
            }
            $score = 0;
            foreach ($nameTokens as $token) {
                if (mb_strlen($token) < 3) {
                    continue;
                }
                if (str_contains($rowName, $token)) {
                    $score++;
                }
            }
            if ($score > $bestScore) {
                $bestScore = $score;
                $bestRow = $row;
            }
        }
        if ($bestRow !== null && $bestScore > 0) {
            if (! empty($bestRow['type']) && empty($result['type'])) {
                $result['type'] = (string) $bestRow['type'];
            }
            if (! empty($bestRow['icon']) && empty($result['icon'])) {
                $result['icon'] = (string) $bestRow['icon'];
            }
            if (($rate === '' || $rate === '0') && isset($bestRow['interestRate']) && is_numeric($bestRow['interestRate']) && ! isset($result['interestRate'])) {
                $result['interestRate'] = (float) $bestRow['interestRate'];
            }
            if (! isset($result['dueDay']) && isset($bestRow['dueDay'])) {
                $result['dueDay'] = (int) $bestRow['dueDay'];
            }
            $suggestions[] = [
                'id' => 'history-debt',
                'label' => 'Used previous debt pattern',
                'detail' => 'Type, APR, and due date were predicted from similar debt',
                'tone' => 'positive',
            ];
        }

        $result['suggestions'] = $suggestions;

        return $result;
    }
}
