"""Display utilities using Rich for beautiful CLI output."""

from typing import Any, Dict, List, Optional

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.syntax import Syntax
from rich.text import Text
from rich.tree import Tree
from rich.markdown import Markdown

console = Console()
error_console = Console(stderr=True)


def print_success(message: str) -> None:
    """Print a success message."""
    console.print(f"[bold green]✓[/bold green] {message}")


def print_error(message: str) -> None:
    """Print an error message."""
    error_console.print(f"[bold red]✗[/bold red] {message}")


def print_warning(message: str) -> None:
    """Print a warning message."""
    console.print(f"[bold yellow]⚠[/bold yellow] {message}")


def print_info(message: str) -> None:
    """Print an info message."""
    console.print(f"[bold blue]ℹ[/bold blue] {message}")


def print_prompt_content(content: str, title: str = "") -> None:
    """Display prompt content in a panel."""
    panel = Panel(
        Markdown(content),
        title=title if title else None,
        border_style="cyan",
        padding=(1, 2),
    )
    console.print(panel)


def print_prompt_list(prompts: list) -> None:
    """Display a table of prompts."""
    if not prompts:
        print_info("No prompts found.")
        return

    table = Table(
        title="[bold]Prompts[/bold]",
        show_header=True,
        header_style="bold cyan",
        border_style="dim",
    )
    table.add_column("Name", style="bold white", min_width=15)
    table.add_column("Versions", justify="center", style="green")
    table.add_column("Tags", style="yellow")
    table.add_column("Latest Hash", style="dim")
    table.add_column("Updated", style="dim")
    table.add_column("Tokens (est.)", justify="right", style="magenta")

    for prompt in prompts:
        tags = ", ".join(
            f"{k}=v{v}" for k, v in prompt.tags.items() if k != "latest"
        )
        latest = prompt.latest
        token_est = str(latest.token_estimate()) if latest else "-"
        short_hash = latest.short_hash if latest else "-"
        updated = prompt.updated_at[:10] if prompt.updated_at else "-"

        table.add_row(
            prompt.name,
            str(prompt.version_count),
            tags or "-",
            short_hash,
            updated,
            token_est,
        )

    console.print(table)


def print_version_history(prompt: Any) -> None:
    """Display version history for a prompt."""
    table = Table(
        title=f"[bold]History: {prompt.name}[/bold]",
        show_header=True,
        header_style="bold cyan",
        border_style="dim",
    )
    table.add_column("Version", justify="center", style="bold")
    table.add_column("Hash", style="dim")
    table.add_column("Message", min_width=20)
    table.add_column("Variables", style="yellow")
    table.add_column("Tokens", justify="right", style="magenta")
    table.add_column("Created", style="dim")
    table.add_column("Tags", style="green")

    # Build tag lookup
    tag_lookup: Dict[int, List[str]] = {}
    for tag_name, ver_num in prompt.tags.items():
        if tag_name == "latest":
            continue
        tag_lookup.setdefault(ver_num, []).append(tag_name)

    for ver in prompt.versions:
        tags = ", ".join(tag_lookup.get(ver.version, []))
        vars_str = ", ".join(ver.variables) if ver.variables else "-"
        table.add_row(
            f"v{ver.version}",
            ver.short_hash,
            ver.message,
            vars_str,
            str(ver.token_estimate()),
            ver.created_at[:10],
            tags or "-",
        )

    console.print(table)
    if prompt.description:
        console.print(f"\n[dim]Description:[/dim] {prompt.description}")


def print_diff(diff_lines: list, name: str, v1: int, v2: int) -> None:
    """Display a colored diff."""
    if not diff_lines:
        print_info(f"No differences between v{v1} and v{v2}")
        return

    console.print(f"\n[bold]Diff: {name} v{v1} → v{v2}[/bold]\n")

    for line in diff_lines:
        content = line["content"]
        line_type = line["type"]

        if line_type == "header":
            console.print(f"[bold]{content}[/bold]")
        elif line_type == "context":
            console.print(f"[cyan]{content}[/cyan]")
        elif line_type == "add":
            console.print(f"[green]{content}[/green]")
        elif line_type == "remove":
            console.print(f"[red]{content}[/red]")
        else:
            console.print(f"[dim]{content}[/dim]")

    console.print()


def print_stats(stats: dict) -> None:
    """Display store statistics."""
    table = Table(
        title="[bold]promptkit Stats[/bold]",
        show_header=False,
        border_style="dim",
    )
    table.add_column("Metric", style="bold")
    table.add_column("Value", justify="right", style="cyan")

    table.add_row("Total Prompts", str(stats["total_prompts"]))
    table.add_row("Total Versions", str(stats["total_versions"]))
    table.add_row("Total Tags", str(stats["total_tags"]))

    console.print(table)


def print_cost_estimate(
    prompt_name: str,
    model: str,
    input_tokens: int,
    output_tokens: int,
    input_cost: float,
    output_cost: float,
) -> None:
    """Display cost estimation."""
    total = input_cost + output_cost

    table = Table(
        title=f"[bold]Cost Estimate: {prompt_name}[/bold]",
        show_header=True,
        header_style="bold cyan",
        border_style="dim",
    )
    table.add_column("", style="bold")
    table.add_column("Tokens", justify="right")
    table.add_column("Cost (per 1M)", justify="right", style="dim")
    table.add_column("Cost", justify="right", style="green")

    table.add_row(
        "Input",
        f"{input_tokens:,}",
        f"${input_cost * 1_000_000 / max(input_tokens, 1):.2f}",
        f"${input_cost:.6f}",
    )
    table.add_row(
        "Output (est.)",
        f"{output_tokens:,}",
        f"${output_cost * 1_000_000 / max(output_tokens, 1):.2f}",
        f"${output_cost:.6f}",
    )
    table.add_row(
        "[bold]Total[/bold]",
        f"[bold]{input_tokens + output_tokens:,}[/bold]",
        "",
        f"[bold green]${total:.6f}[/bold green]",
    )

    console.print(table)
    console.print(f"\n[dim]Model: {model}[/dim]")


def print_init_success(directory: str) -> None:
    """Display init success message."""
    tree = Tree("[bold green]✓ Initialized promptkit project[/bold green]")
    pk = tree.add("[bold].promptkit/[/bold]")
    pk.add("[cyan]config.json[/cyan] — Configuration")
    pk.add("[cyan]prompts/[/cyan] — Prompt storage")
    pk.add("[cyan]tests/[/cyan] — Test definitions")
    pk.add("[dim]cache/[/dim] — Temporary files")
    pk.add("[dim].gitignore[/dim]")
    console.print(tree)
    console.print(f"\n[dim]Project: {directory}[/dim]")
    console.print("[dim]Get started: promptkit save my-prompt --content 'Your prompt here'[/dim]")
