"""Output mode resolution and rendering.

The CLI decides *what* to render; this module decides *how* to render it.
"""

from __future__ import annotations

from enum import Enum
from typing import Any

from rich.console import Console

from arxivy.formatters.bibtex import format_bibtex, format_bibtex_batch
from arxivy.formatters.json_fmt import format_json
from arxivy.formatters.table import format_paper_detail, format_papers_table
from arxivy.models import Paper, PaperListResult


class OutputMode(str, Enum):
    AUTO = "auto"
    TABLE = "table"
    JSON = "json"
    BIBTEX = "bibtex"


def resolve_output_mode(*, use_json: bool, use_bibtex: bool, is_tty: bool) -> OutputMode:
    """Resolve the effective output mode.

    Priority: bibtex > json > table.
    When not attached to a TTY, default to JSON.
    """
    if use_bibtex:
        return OutputMode.BIBTEX
    if use_json:
        return OutputMode.JSON
    if not is_tty:
        return OutputMode.JSON
    return OutputMode.TABLE


def render_to_string(
    data: Paper | PaperListResult | list[Paper] | dict[str, Any],
    *,
    mode: OutputMode,
    pretty: bool,
) -> str:
    """Render output formats that are pure text."""
    if mode is OutputMode.BIBTEX:
        if isinstance(data, PaperListResult):
            return format_bibtex_batch(data.results)
        if isinstance(data, list):
            return format_bibtex_batch(data)
        if isinstance(data, Paper):
            return format_bibtex(data)
        raise TypeError(f"Unsupported data for bibtex: {type(data)!r}")

    if mode is OutputMode.JSON:
        return format_json(data, pretty=pretty)

    raise ValueError(f"render_to_string only supports JSON/BibTeX, got {mode}")


def render_to_console(
    data: Paper | PaperListResult | list[Paper],
    *,
    console: Console,
    show_abstract: bool = False,
) -> None:
    """Render rich output to a console."""
    if isinstance(data, Paper):
        console.print(format_paper_detail(data))
        return

    if isinstance(data, PaperListResult):
        console.print(format_papers_table(data.results, meta=data.meta, show_abstract=show_abstract))
        return

    if isinstance(data, list):
        console.print(format_papers_table(data, show_abstract=show_abstract))
        return

    raise TypeError(f"Unsupported data for console rendering: {type(data)!r}")
