<?php

namespace App\Support;

/**
 * Mirrors inferBudgetInput from bugets-smart-money/src/lib/smart-form.ts
 *
 * @return array{
 *     categoryId?: string,
 *     icon?: string,
 *     period?: string,
 *     limit?: float,
 *     suggestions: list<array{id: string, label: string, detail?: string, tone?: string}>
 * }
 */
final class BudgetInference
{
    /** @var list<array{match: list<string>, icon: string, categoryId: string, limit: float}> */
    private const BUDGET_ICON_MAP = [
        ['match' => ['pet insurance', 'dog insurance', 'cat insurance'], 'icon' => '🐾', 'categoryId' => 'insurance', 'limit' => 80],
        ['match' => ['car insurance', 'auto insurance', 'motor insurance'], 'icon' => '🚗', 'categoryId' => 'insurance', 'limit' => 120],
        ['match' => ['home insurance', 'house insurance', 'renters insurance'], 'icon' => '🏠', 'categoryId' => 'insurance', 'limit' => 100],
        ['match' => ['life insurance'], 'icon' => '🛡️', 'categoryId' => 'insurance', 'limit' => 100],
        ['match' => ['health insurance', 'medical insurance'], 'icon' => '🏥', 'categoryId' => 'insurance', 'limit' => 120],
        ['match' => ['rent', 'mortgage', 'lease', 'landlord', 'housing', 'aluguel', 'hipoteca', 'condominio'], 'icon' => '🏠', 'categoryId' => 'housing', 'limit' => 1200],
        ['match' => ['pet', 'pets', 'veterinary', 'vet', 'dog food', 'cat food'], 'icon' => '🐾', 'categoryId' => 'pets', 'limit' => 150],
        ['match' => ['insurance'], 'icon' => '🛡️', 'categoryId' => 'insurance', 'limit' => 150],
        ['match' => ['food', 'dining', 'grocery'], 'icon' => '🍕', 'categoryId' => 'food', 'limit' => 600],
        ['match' => ['transport', 'car', 'uber'], 'icon' => '🚗', 'categoryId' => 'transport', 'limit' => 200],
        ['match' => ['entertainment', 'streaming', 'fun'], 'icon' => '🎬', 'categoryId' => 'entertainment', 'limit' => 150],
        ['match' => ['shopping', 'clothes'], 'icon' => '🛍️', 'categoryId' => 'shopping', 'limit' => 300],
        ['match' => ['health', 'fitness', 'gym'], 'icon' => '💪', 'categoryId' => 'health', 'limit' => 100],
        ['match' => ['utilities', 'bills'], 'icon' => '⚡', 'categoryId' => 'utilities', 'limit' => 150],
        ['match' => ['subscriptions', 'membership', 'saas'], 'icon' => '🔁', 'categoryId' => 'subscriptions', 'limit' => 120],
    ];

    public static function infer(string $name, array $history = []): array
    {
        $input = mb_strtolower(trim($name));
        $suggestions = [];
        $result = ['suggestions' => $suggestions, 'period' => 'monthly'];

        $detected = CategoryDetector::detect($name);
        if ($detected !== null && $detected !== 'income') {
            $result['categoryId'] = $detected;
        }

        foreach (self::BUDGET_ICON_MAP as $rule) {
            if (! FinancialKeywordMatch::containsAny($name, $rule['match'])) {
                continue;
            }
            $result['icon'] = $rule['icon'];
            $result['categoryId'] = $result['categoryId'] ?? $rule['categoryId'];
            $result['limit'] = $rule['limit'];
            $suggestions[] = [
                'id' => 'budget-'.$rule['categoryId'],
                'label' => 'Prefilled '.$rule['categoryId'].' defaults',
                'detail' => 'Suggested limit €'.(int) $rule['limit'].'/month',
                'tone' => 'positive',
            ];
            $result['suggestions'] = $suggestions;
            break;
        }

        if (str_contains($input, 'annual') || str_contains($input, 'year')) {
            $result['period'] = 'yearly';
        }
        if (str_contains($input, 'week')) {
            $result['period'] = 'weekly';
        }

        // Learn likely limit/category from similar existing budgets.
        $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($result['categoryId']) && ! empty($bestRow['categoryId'])) {
                $result['categoryId'] = (string) $bestRow['categoryId'];
            }
            if (empty($result['icon']) && ! empty($bestRow['icon'])) {
                $result['icon'] = (string) $bestRow['icon'];
            }
            if (! isset($result['limit']) && isset($bestRow['limit']) && is_numeric($bestRow['limit'])) {
                $result['limit'] = (float) $bestRow['limit'];
                $suggestions[] = [
                    'id' => 'history-limit',
                    'label' => 'Predicted budget limit from similar budget',
                    'detail' => 'Suggested €'.number_format((float) $bestRow['limit'], 0, ',', '.').' / month',
                    'tone' => 'positive',
                ];
            }
        }

        $result['suggestions'] = $suggestions;

        return $result;
    }
}
