"""Output formatters -- table, JSON, CSV."""

from __future__ import annotations

import csv
import io
import json
from typing import Any

from rich.console import Console
from rich.table import Table

console = Console()
err_console = Console(stderr=True)


def render_table(
    data: list[dict[str, Any]],
    columns: dict[str, str],
    title: str | None = None,
) -> None:
    """Render data as a rich table. columns maps display name -> data key."""
    table = Table(title=title, show_lines=False)
    for display_name in columns:
        table.add_column(display_name, style="cyan" if display_name == "ID" else None)

    for row in data:
        values = []
        for key in columns.values():
            val = row.get(key, "")
            if val is None:
                val = "-"
            elif isinstance(val, bool):
                val = "Yes" if val else "No"
            elif isinstance(val, list):
                val = ", ".join(str(v) for v in val)
            values.append(str(val))
        table.add_row(*values)

    console.print(table)


def render_detail(data: dict[str, Any], title: str | None = None) -> None:
    """Render a single item as a key-value detail view."""
    if title:
        console.print(f"\n[bold]{title}[/bold]")
    for key, raw_value in data.items():
        display = raw_value
        if display is None:
            display = "-"
        elif isinstance(display, (dict, list)):
            display = json.dumps(display, indent=2, default=str)
        console.print(f"  [bold]{key}[/bold]: {display}")
    console.print()


def render_json(data: Any) -> None:
    """Output raw JSON to stdout."""
    console.print_json(json.dumps(data, default=str))


def render_csv(data: list[dict[str, Any]], columns: dict[str, str]) -> None:
    """Output data as CSV."""
    output = io.StringIO()
    writer = csv.writer(output)
    writer.writerow(columns.keys())
    for row in data:
        writer.writerow(str(row.get(key, "")) for key in columns.values())
    console.print(output.getvalue(), highlight=False)


def render(
    data: Any,
    output_format: str = "table",
    columns: dict[str, str] | None = None,
    title: str | None = None,
    is_list: bool = True,
) -> None:
    """Unified render dispatcher."""
    if output_format == "json":
        render_json(data)
        return

    if not is_list:
        if output_format == "table":
            render_detail(data, title=title)
        return

    if not columns:
        render_json(data)
        return

    if output_format == "csv":
        render_csv(data, columns)
    else:
        render_table(data, columns, title=title)


def render_meta(meta: dict[str, Any], output_format: str = "table") -> None:
    """Render pagination metadata."""
    if output_format != "table":
        return
    total = meta.get("total", 0)
    skip = meta.get("skip", 0)
    limit = meta.get("limit", 100)
    end = min(skip + limit, total)
    err_console.print(f"[dim]Showing {skip + 1}-{end} of {total}[/dim]")


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


def error(message: str) -> None:
    """Print an error message to stderr."""
    err_console.print(f"[red]error[/red] {message}")


def warn(message: str) -> None:
    """Print a warning message to stderr."""
    err_console.print(f"[yellow]warn[/yellow] {message}")


def info(message: str) -> None:
    """Print an info message to stderr."""
    err_console.print(f"[blue]info[/blue] {message}")
