"""Centralized CLI output manager and helper functions.

This module provides a unified interface for CLI error handling and user
feedback, implementing the centralized output strategy described in the
refactoring of CLI commands.

The CLIOutputManager class wraps the existing OutputSession
infrastructure and provides convenience methods for common CLI output
patterns: success/warning/info messages, error panels, success panels,
and formatted tables.

Helper functions (display_success, display_warning, etc.) are
provided as module-level shortcuts for callers that do not need a full
manager instance.
"""

from __future__ import annotations

import sys
import traceback
from typing import Any


def display_success(
    message: str,
    *,
    output_format: str = "rich",
) -> None:
    """Display a success message to stdout."""
    if output_format in ("json", "yaml"):
        import json as _json

        print(_json.dumps({"status": "success", "message": message}), file=sys.stdout)
    elif output_format == "plain":
        print(f"✓ {message}", file=sys.stdout)
    else:
        print(f"[green]✓ {message}[/green]", file=sys.stdout)


def display_warning(
    message: str,
    *,
    output_format: str = "rich",
) -> None:
    """Display a warning message to stdout."""
    if output_format in ("json", "yaml"):
        import json as _json

        print(_json.dumps({"status": "warning", "message": message}), file=sys.stdout)
    elif output_format == "plain":
        print(f"⚠ {message}", file=sys.stdout)
    else:
        print(f"[yellow]⚠ {message}[/yellow]", file=sys.stdout)


def display_info(
    message: str,
    *,
    output_format: str = "rich",
) -> None:
    """Display an informational message to stdout."""
    if output_format in ("json", "yaml"):
        import json as _json

        print(_json.dumps({"status": "info", "message": message}), file=sys.stdout)
    elif output_format == "plain":
        print(f"i {message}", file=sys.stdout)
    else:
        print(f"[blue]i {message}[/blue]", file=sys.stdout)


def display_error_panel(
    title: str,
    content: str,
    *,
    output_format: str = "rich",
) -> None:
    """Display an error panel to stderr."""
    if output_format in ("json", "yaml"):
        import json as _json

        data = {"status": "error", "title": title, "content": content}
        print(_json.dumps(data), file=sys.stderr)
    elif output_format == "plain":
        print(f"Error: {title}", file=sys.stderr)
        print(content, file=sys.stderr)
    else:
        border = "─" * (len(title) + 4)
        lines = [
            f"[red]┌─ {title} ─┐",
            f"│ {content} │",
            f"└{border}┘[/red]",
        ]
        print(chr(10).join(lines), file=sys.stderr)


def display_success_panel(
    title: str,
    content: str,
    *,
    output_format: str = "rich",
) -> None:
    """Display a success panel to stdout."""
    if output_format in ("json", "yaml"):
        import json as _json

        data = {"status": "success", "title": title, "content": content}
        print(_json.dumps(data), file=sys.stdout)
    elif output_format == "plain":
        print(f"Success: {title}", file=sys.stdout)
        print(content, file=sys.stdout)
    else:
        border = "─" * (len(title) + 4)
        lines = [
            f"[green]┌─ {title} ─┐",
            f"│ {content} │",
            f"└{border}┘[/green]",
        ]
        print(chr(10).join(lines), file=sys.stdout)


def display_table(
    title: str,
    columns: list[tuple[str, Any]],
    rows: list[list[Any]],
    *,
    output_format: str = "rich",
) -> None:
    """Display a formatted table to stdout."""
    col_names = [col[0] for col in columns]

    if output_format == "json":
        import json as _json

        data: dict[str, Any] = {
            "title": title,
            "columns": col_names,
            "rows": [list(row) for row in rows],
        }
        print(_json.dumps(data), file=sys.stdout)
    elif output_format == "yaml":
        print(f"title: {title}", file=sys.stdout)
        print(f"columns: {col_names}", file=sys.stdout)
        print("rows:", file=sys.stdout)
        for row in rows:
            print(f"  - {list(row)}", file=sys.stdout)
    elif output_format == "plain":
        print(title, file=sys.stdout)
        print("  ".join(col_names), file=sys.stdout)
        for row in rows:
            print("  ".join(str(cell) for cell in row), file=sys.stdout)
    else:
        print(f"[bold]{title}[/bold]", file=sys.stdout)
        header = "  ".join(f"[bold]{col}[/bold]" for col in col_names)
        print(header, file=sys.stdout)
        for row in rows:
            print("  ".join(str(cell) for cell in row), file=sys.stdout)


class CLIOutputManager:
    """Centralized manager for CLI output and error handling."""

    def __init__(
        self,
        *,
        debug: bool = False,
        output_format: str = "rich",
    ) -> None:
        """Initialise the output manager."""
        self.debug = debug
        self.output_format = output_format

    def display_success(self, message: str) -> None:
        """Display a success message to stdout."""
        display_success(message, output_format=self.output_format)

    def display_warning(self, message: str) -> None:
        """Display a warning message to stdout."""
        display_warning(message, output_format=self.output_format)

    def display_info(self, message: str) -> None:
        """Display an informational message to stdout."""
        display_info(message, output_format=self.output_format)

    def display_success_panel(self, title: str, content: str) -> None:
        """Display a success panel to stdout."""
        display_success_panel(title, content, output_format=self.output_format)

    def display_error_panel(self, title: str, content: str) -> None:
        """Display an error panel to stderr."""
        display_error_panel(title, content, output_format=self.output_format)

    def display_table(
        self,
        title: str,
        columns: list[tuple[str, Any]],
        rows: list[list[Any]],
    ) -> None:
        """Display a formatted table to stdout."""
        display_table(title, columns, rows, output_format=self.output_format)

    def handle_exception(
        self,
        exc: BaseException,
        *,
        label: str = "Error",
    ) -> None:
        """Handle an exception by displaying a user-friendly error message."""
        message = str(exc)
        if self.output_format in ("json", "yaml"):
            import json as _json

            print(
                _json.dumps({"status": "error", "label": label, "message": message}),
                file=sys.stderr,
            )
        elif self.output_format == "plain":
            print(f"Error [{label}]: {message}", file=sys.stderr)
        else:
            print(f"[red]Error [{label}]: {message}[/red]", file=sys.stderr)
        if self.debug:
            traceback.print_exc(file=sys.stderr)


__all__ = [
    "CLIOutputManager",
    "display_error_panel",
    "display_info",
    "display_success",
    "display_success_panel",
    "display_table",
    "display_warning",
]
