from __future__ import annotations

from pathlib import Path

from rich.console import Console

from ..engine.types import Cost, ToolCall, Usage
from ..session import Session
from sunwaee import __version__
from sunwaee.core.git import render_diff

_console = Console()


def show_banner() -> None:
    _cwd = Path.cwd()
    try:
        cwd = "~/" + str(_cwd.relative_to(Path.home()))
    except ValueError:
        cwd = str(_cwd)

    _console.print()
    _console.print("  [bold white]SUNWÆE CLI[/bold white]")
    _console.print(f"  [#787d82]v{__version__}[/#787d82]")
    _console.print(f"  [#787d82]{cwd}[/#787d82]")
    _console.print()


def show_help() -> None:
    _console.print("  [bold]:h, :help[/bold]          show this help")
    _console.print("  [bold]:q, :quit, :exit[/bold]   quit the REPL")
    _console.print("  [bold]:clear[/bold]             clear conversation history")
    _console.print("  [bold]:session[/bold]           show current session info")
    _console.print(
        "  [bold]:cost[/bold]              show accumulated cost and token usage"
    )
    _console.print("  [bold]:model[/bold]             show current model")
    _console.print("  [bold]:model <name>[/bold]      switch to a different model")


def show_session(
    session: Session, cost: Cost | None = None, usage: Usage | None = None
) -> None:
    _console.print(f"  [bold]id[/bold]         {session.id}")
    _console.print(f"  [bold]title[/bold]      {session.title or '(untitled)'}")
    _console.print(f"  [bold]workspace[/bold]  {session.workspace}")
    _console.print(f"  [bold]created[/bold]    {session.created_at}")
    _console.print(f"  [bold]updated[/bold]    {session.updated_at}")
    if cost is not None and usage is not None:
        _console.print()
        show_cost(cost, usage)


def show_cost(cost: Cost, usage: Usage) -> None:
    has_cache = usage.cache_read_tokens or usage.cache_write_tokens
    regular_input = max(
        0, usage.input_tokens - usage.cache_read_tokens - usage.cache_write_tokens
    )

    if has_cache:
        _console.print(
            f"  [bold]tokens[/bold]   in {usage.input_tokens:,}"
            f"  (reg {regular_input:,} · write {usage.cache_write_tokens:,} · read {usage.cache_read_tokens:,})"
            f"  out {usage.output_tokens:,}  total {usage.total_tokens:,}"
        )
        _console.print(
            f"  [bold]cost[/bold]     in ${cost.input:.6f}"
            f"  write ${cost.cache_write:.6f}  read ${cost.cache_read:.6f}"
            f"  out ${cost.output:.6f}  total ${cost.total:.6f}"
        )
    else:
        _console.print(
            f"  [bold]tokens[/bold]   in {usage.input_tokens:,}"
            f"  out {usage.output_tokens:,}  total {usage.total_tokens:,}"
        )
        _console.print(
            f"  [bold]cost[/bold]     in ${cost.input:.6f}"
            f"  out ${cost.output:.6f}  total ${cost.total:.6f}"
        )


def show_tool_calls(tool_calls: list[ToolCall]) -> None:
    for tc in tool_calls:
        _render_tool_call(tc)


def _render_tool_call(tc: ToolCall) -> None:
    result: dict = tc.results[0] if tc.results else {}
    is_ok = result.get("ok", not bool(tc.error))
    data = result.get("data", {})
    git_diff: str = result.get("git_diff", "")

    label = _tool_label(tc)
    status = "[green]✓[/green]" if is_ok else "[red]✗[/red]"
    duration = f"[dim]{tc.duration}s[/dim]" if tc.duration else ""

    _console.print(f"\n  [dim]↳ {tc.name}[/dim]  {label}  {status}  {duration}")

    if tc.error:
        _console.print(f"  [red]{tc.error}[/red]")
        return

    if not is_ok:
        error_msg = result.get("error", "")
        if error_msg:
            _console.print(f"  [red]{error_msg}[/red]")
        return

    if git_diff:
        render_diff(git_diff)
        return

    # no diff — show a contextual summary
    if tc.name == "shell":
        stdout = (data.get("stdout") or "").strip()
        stderr = (data.get("stderr") or "").strip()
        git_status = result.get("git_status", "").strip()
        if stdout:
            _console.print(
                "  " + stdout[:800], markup=False, highlight=False, style="#787d82"
            )
        if stderr:
            _console.print(
                "  " + stderr[:400], markup=False, highlight=False, style="red"
            )
        if git_status and not stdout:
            _console.print(
                "  " + git_status, markup=False, highlight=False, style="#787d82"
            )
    elif isinstance(data, list):
        _console.print(f"  [dim]{len(data)} item(s)[/dim]")
    elif isinstance(data, dict):
        title = data.get("title") or data.get("name") or data.get("id", "")
        if title:
            _console.print(f"  [dim]{title}[/dim]")


def _tool_label(tc: ToolCall) -> str:
    if tc.name == "shell":
        return tc.arguments.get("comment", tc.arguments.get("command", ""))[:80]
    action = tc.arguments.get("action", "")
    item = (
        tc.arguments.get("title")
        or tc.arguments.get("query")
        or tc.arguments.get("name")
        or ""
    )
    return f"{action} '{item}'" if item else action

