from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar

from textual.reactive import reactive
from textual.widget import Widget
from textual.widgets import Static

if TYPE_CHECKING:
    from textual.app import ComposeResult

    from smartwallet.model.base import BudgetComponent

from smartwallet.model.category import Category
from smartwallet.model.transaction import Transaction

_LABEL = "#9ca3af"
_VALUE = "#f5f5f5"
_INCOME = "#10b981"
_EXPENSE = "#ef4444"
_BLUE = "#3b82f6"
_GREEN = "#22c55e"
_INDIGO = "#6366f1"
_PURPLE = "#a855f7"
_DIM = "#52525b"


def _amount_color(value: float) -> str:
    if value > 0:
        return _INCOME
    if value < 0:
        return _EXPENSE
    return _DIM


class DetailPanel(Widget):
    BORDER_TITLE: ClassVar[str] = "Details"

    selected: reactive[BudgetComponent | None] = reactive(None)

    def compose(self) -> ComposeResult:
        yield Static(
            f"[{_LABEL}]Select a node to view details.[/]",
            id="detail-content",
        )

    def watch_selected(self, value: BudgetComponent | None) -> None:
        content = self.query_one("#detail-content", Static)
        if value is None:
            content.update(f"[{_LABEL}]Select a node to view details.[/]")
            return

        if isinstance(value, Category):
            content.update(self._format_category(value))
        elif isinstance(value, Transaction):
            content.update(self._format_transaction(value))

    @staticmethod
    def _format_category(category: Category) -> str:
        balance = category.get_balance()
        income = balance["income"]
        expense = balance["expense"]
        total = balance["total"]
        total_clr = _amount_color(total)

        children_count = len(category.children)
        cat_count = sum(1 for c in category.children if isinstance(c, Category))
        txn_count = children_count - cat_count

        return (
            f"[bold {_INDIGO}]Category[/]  [{_VALUE}]{category.name}[/]\n"
            f"[{_DIM}]{'─' * 36}[/]\n"
            f"\n"
            f"  [{_LABEL}]Income:[/]   [{_INCOME}]{income:>12.2f}[/]\n"
            f"  [{_LABEL}]Expense:[/]  [{_EXPENSE}]{expense:>12.2f}[/]\n"
            f"  [{_LABEL}]Total:[/]    [{total_clr}]{total:>12.2f}[/]\n"
            f"\n"
            f"[{_DIM}]{'─' * 36}[/]\n"
            f"  [{_LABEL}]Children:[/]      [{_BLUE}]{children_count}[/]\n"
            f"  [{_LABEL}]Categories:[/]    [{_BLUE}]{cat_count}[/]\n"
            f"  [{_LABEL}]Transactions:[/]  [{_BLUE}]{txn_count}[/]\n"
            f"  [{_LABEL}]Created:[/]       [{_VALUE}]{category.created_at}[/]"
        )

    @staticmethod
    def _format_transaction(transaction: Transaction) -> str:
        is_income = transaction.amount >= 0
        kind = "Income" if is_income else "Expense"
        kind_clr = _INCOME if is_income else _EXPENSE
        amt_clr = _amount_color(transaction.amount)

        return (
            f"[bold {_PURPLE}]Transaction[/]  [{_VALUE}]{transaction.name}[/]\n"
            f"[{_DIM}]{'─' * 36}[/]\n"
            f"\n"
            f"  [{_LABEL}]Type:[/]     [{kind_clr}]{kind}[/]\n"
            f"  [{_LABEL}]Amount:[/]   [{amt_clr}]{transaction.amount:.2f}[/]\n"
            f"  [{_LABEL}]Date:[/]     [{_VALUE}]{transaction.transaction_date}[/]\n"
            f"\n"
            f"[{_DIM}]{'─' * 36}[/]\n"
            f"  [{_LABEL}]Created:[/]  [{_VALUE}]{transaction.created_at}[/]"
        )
