from __future__ import annotations

from datetime import datetime
from typing import Any

from rich.console import Group
from rich.pretty import Pretty
from rich.table import Table
from rich.text import Text


def format_value(value: Any) -> str:
    if value is None:
        return "—"
    if isinstance(value, bool):
        return "yes" if value else "no"
    if isinstance(value, float):
        if abs(value) >= 1_000:
            return f"{value:,.2f}"
        return f"{value:.4f}".rstrip("0").rstrip(".")
    if isinstance(value, datetime):
        return value.isoformat()
    if isinstance(value, list):
        return ", ".join(format_value(item) for item in value)
    return str(value)


def make_kv_table(title: str, values: dict[str, Any]) -> Table:
    table = Table(title=title, show_header=False, box=None, pad_edge=False)
    table.add_column("key", style="cyan", no_wrap=True)
    table.add_column("value")
    for key, value in values.items():
        table.add_row(key, format_value(value))
    return table


def make_rows_table(
    title: str,
    rows: list[dict[str, Any]],
    columns: list[str] | None = None,
    limit: int | None = None,
) -> Table:
    table = Table(title=title, expand=True)
    if not rows:
        table.add_column("status")
        table.add_row("No rows")
        return table
    ordered_columns = columns or list(rows[0].keys())
    for column in ordered_columns:
        table.add_column(column)
    for row in rows[:limit]:
        table.add_row(*(format_value(row.get(column)) for column in ordered_columns))
    return table


def make_warning_text(warnings: list[str]) -> Text | None:
    if not warnings:
        return None
    text = Text()
    for warning in warnings:
        text.append(f"warning: {warning}\n", style="yellow")
    return text


def group_parts(*parts: Any) -> Group:
    filtered = [part for part in parts if part is not None]
    return Group(*filtered)


def pretty_block(title: str, value: Any) -> Table:
    table = Table(title=title, box=None, pad_edge=False)
    table.add_column("data")
    table.add_row(Pretty(value, expand_all=True))
    return table
