<?php

namespace App\Livewire;

use App\Services\FinanceRepository;
use App\Support\DebtDueDate;
use App\Support\FinanceDataInsights;
use App\Support\Money;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.app')]
class AiAdvisorPage extends Component
{
    /** @var array<int, int> */
    private const QUICK_TO_SCENARIO = [0, 1, 5, 3, 4];

    /** @var list<array{role: string, text: string}> */
    public array $messages = [];

    public string $input = '';

    /** @var list<string> */
    public array $pendingReplies = [];

    public function mount(): void
    {
        $this->messages = [[
            'role' => 'ai',
            'text' => (string) __('budgets.ai_advisor_page.greeting'),
        ]];
    }

    /** @return list<string> */
    public function quickPrompts(): array
    {
        $list = __('budgets.ai_advisor_page.quick_prompts');

        return is_array($list) ? array_values($list) : [];
    }

    public function send(?string $quickPrompt = null): void
    {
        $text = $quickPrompt !== null ? $quickPrompt : trim($this->input);
        if ($text === '') {
            return;
        }

        $this->messages[] = ['role' => 'user', 'text' => $text];
        $this->input = '';
        $this->pendingReplies[] = $this->resolveAiReply($text);

        // React behavior parity: show user message immediately, delay AI response.
        $this->js("setTimeout(() => { const el = document.getElementById('ai-advisor-messages'); if (el) el.scrollTop = el.scrollHeight; }, 0); setTimeout(() => \$wire.completeReply(), 800);");
    }

    public function completeReply(): void
    {
        if (count($this->pendingReplies) === 0) {
            return;
        }

        $this->messages[] = [
            'role' => 'ai',
            'text' => array_shift($this->pendingReplies),
        ];

        $this->js("setTimeout(() => { const el = document.getElementById('ai-advisor-messages'); if (el) el.scrollTop = el.scrollHeight; }, 0);");
    }

    protected function resolveAiReply(string $text): string
    {
        // 1) Exact prompt match first (mirrors React "scenario_q exact match").
        $scenarios = $this->scenarios();
        foreach ($scenarios as $s) {
            if (trim($text) === trim($s['q'])) {
                return $s['a'];
            }
        }

        // 2) Quick prompts map to fixed scenario indices (React QUICK_TO_SCENARIO).
        $quickPrompts = $this->quickPrompts();
        $quickIndex = array_search($text, $quickPrompts, true);
        if ($quickIndex !== false) {
            $mappedScenario = self::QUICK_TO_SCENARIO[$quickIndex] ?? null;
            if ($mappedScenario !== null && isset($scenarios[$mappedScenario]['a'])) {
                return $scenarios[$mappedScenario]['a'];
            }
        }

        // 3) Fuzzy matcher from React page for ad-hoc input.
        $guessed = $this->matchScenarioFromText($text);
        if ($guessed !== null && isset($scenarios[$guessed]['a'])) {
            return $scenarios[$guessed]['a'];
        }

        return $this->defaultReply();
    }

    protected function matchScenarioFromText(string $text): ?int
    {
        if (preg_match('/100\s*,?\s*00\s*€?\s*(more|extra|mais|por)/iu', $text) === 1 ||
            (mb_stripos($text, 'poupar') !== false && preg_match('/100/u', $text) === 1)) {
            return 0;
        }

        if (preg_match('/netflix/iu', $text) === 1) {
            return 1;
        }

        if (preg_match('/200\s*,?\s*00\s*€?/iu', $text) === 1 &&
            preg_match('/(card|cart|credito|crédito)/iu', $text) === 1) {
            return 2;
        }

        if (preg_match('/10\s*%/u', $text) === 1 || preg_match('/income|renda/iu', $text) === 1) {
            return 3;
        }

        if (preg_match('/rent|aluguer|aluguel/iu', $text) === 1) {
            return 4;
        }

        if (preg_match('/debt|dívida|divida/iu', $text) === 1 &&
            preg_match('/fast|rapido|rápido|sooner/iu', $text) === 1) {
            return 5;
        }

        return null;
    }

    /**
     * @return list<array{q: string, a: string}>
     */
    protected function scenarios(): array
    {
        $list = __('budgets.ai_advisor_page.scenarios');

        if (! is_array($list)) {
            return [];
        }

        $out = [];
        foreach ($list as $row) {
            if (is_array($row) && isset($row['q'], $row['a'])) {
                $out[] = ['q' => (string) $row['q'], 'a' => (string) $row['a']];
            }
        }

        return $out;
    }

    protected function defaultReply(): string
    {
        $finance = app(FinanceRepository::class);
        if (! FinanceDataInsights::hasFinanceContext($finance)) {
            return (string) __('budgets.ai_advisor_page.default_reply_empty');
        }

        $tx = $finance->transactions();
        $subs = $finance->subscriptions();
        $debts = $finance->debts();
        $balance = (float) collect($tx)->sum('amount');
        $flow = FinanceDataInsights::monthCashFlowFromTransactions($tx);
        $activeSubs = count(array_filter($subs, fn ($s) => in_array($s['status'] ?? '', ['active', 'trial'], true)));
        $debtNames = collect($debts)
            ->filter(fn ($d) => (float) ($d['balance'] ?? 0) > 0.009)
            ->sortBy(fn ($d) => DebtDueDate::nextOccurrenceTimestamp($d))
            ->take(3)
            ->pluck('name')
            ->filter()
            ->join(', ');
        $debtNote = $debtNames !== ''
            ? (string) __('budgets.ai_advisor_page.default_reply_debt_note', ['list' => $debtNames])
            : '';

        return (string) __('budgets.ai_advisor_page.default_reply_summary', [
            'balance' => Money::formatEur($balance),
            'income' => Money::formatEur($flow['income']),
            'expenses' => Money::formatEur($flow['expenses']),
            'count' => $activeSubs,
            'debt_note' => $debtNote,
        ]);
    }

    public function render()
    {
        return view('livewire.ai-advisor-page', [
            'quickPrompts' => $this->quickPrompts(),
        ])->title((string) __('budgets.ai_advisor_page.title'));
    }
}
