"""
Output formatting utilities for CLI.
"""

import json
from typing import Any, Optional

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

console = Console()


class OutputFormatter:
    """Handles output formatting for CLI commands."""

    def __init__(self, json_output: bool = True):
        """
        Initialize output formatter.

        Args:
            json_output: Whether to output in JSON format (default True for AI)
        """
        self.json_output = json_output

    def format(self, data: Any) -> str:
        """
        Format data for output.

        Args:
            data: Data to format (dict, list, or any serializable object)

        Returns:
            Formatted string
        """
        if self.json_output:
            return self._format_json(data)
        return self._format_human(data)

    def _format_json(self, data: Any) -> str:
        """Format data as JSON."""
        if hasattr(data, "model_dump"):
            data = data.model_dump()
        return orjson.dumps(data, option=orjson.OPT_INDENT_2).decode("utf-8")

    def _format_human(self, data: Any) -> str:
        """Format data for human reading."""
        if isinstance(data, dict):
            return self._format_dict_human(data)
        elif isinstance(data, list):
            return self._format_list_human(data)
        return str(data)

    def _format_dict_human(self, data: dict) -> str:
        """Format dictionary for human reading."""
        lines = []
        for key, value in data.items():
            if isinstance(value, list) and len(value) > 0 and isinstance(value[0], dict):
                lines.append(f"\n{key}:")
                for item in value:
                    for k, v in item.items():
                        lines.append(f"  {k}: {v}")
                    lines.append("  ---")
            else:
                lines.append(f"{key}: {value}")
        return "\n".join(lines)

    def _format_list_human(self, data: list) -> str:
        """Format list for human reading."""
        if not data:
            return "(empty)"
        if isinstance(data[0], dict):
            lines = []
            for i, item in enumerate(data, 1):
                lines.append(f"[{i}]")
                for k, v in item.items():
                    lines.append(f"  {k}: {v}")
            return "\n".join(lines)
        return "\n".join(str(item) for item in data)

    def print(self, data: Any) -> None:
        """Print formatted output to console."""
        output = self.format(data)
        if self.json_output:
            console.print_json(output)
        else:
            console.print(output)

    def print_table(
        self,
        title: str,
        columns: list[str],
        rows: list[list[Any]],
    ) -> None:
        """
        Print a table (human-readable only, falls back to JSON if json_output=True).
        """
        if self.json_output:
            data = [dict(zip(columns, row)) for row in rows]
            self.print(data)
        else:
            table = Table(title=title)
            for col in columns:
                table.add_column(col)
            for row in rows:
                table.add_row(*[str(cell) for cell in row])
            console.print(table)

    def print_error(self, message: str, code: Optional[str] = None) -> None:
        """Print error message."""
        if self.json_output:
            error_data = {"error": True, "message": message}
            if code:
                error_data["code"] = code
            console.print_json(orjson.dumps(error_data).decode("utf-8"))
        else:
            console.print(f"[red]Error:[/red] {message}")
            if code:
                console.print(f"[red]Code:[/red] {code}")

    def print_success(self, message: str, data: Optional[Any] = None) -> None:
        """Print success message."""
        if self.json_output:
            result = {"success": True, "message": message}
            if data is not None:
                result["data"] = data
            console.print_json(orjson.dumps(result).decode("utf-8"))
        else:
            console.print(f"[green]Success:[/green] {message}")
            if data is not None:
                console.print(data)


def format_output(data: Any, json_output: bool = True) -> str:
    """
    Quick utility to format output.

    Args:
        data: Data to format
        json_output: Whether to use JSON format

    Returns:
        Formatted string
    """
    formatter = OutputFormatter(json_output=json_output)
    return formatter.format(data)
