"""Rich table formatting for arXiv papers.

Formatters should return Rich renderables; printing belongs in the CLI.
"""

from __future__ import annotations

from typing import Any

from rich.panel import Panel
from rich.table import Table
from rich.text import Text

from arxivy.models import Author, Paper, PaperListMeta


def _truncate(text: str, max_length: int = 60) -> str:
    if not text:
        return ""
    if len(text) <= max_length:
        return text
    return text[: max_length - 3] + "..."


def _format_authors(authors: list[Author], max_length: int = 30) -> str:
    if not authors:
        return ""
    names = [a.name for a in authors]
    if len(names) > 2:
        result = f"{names[0]} et al."
    else:
        result = ", ".join(names)
    return _truncate(result, max_length)


def _year_from_date(date_str: str) -> str:
    if date_str and len(date_str) >= 4:
        return date_str[:4]
    return ""


def format_papers_table(
    papers: list[Paper],
    meta: PaperListMeta | dict[str, Any] | None = None,
    show_abstract: bool = False,
) -> Table:
    """Build a Rich table for a list of papers.

    Args:
        papers: List of Paper objects to display.
        meta: Optional pagination metadata.
        show_abstract: If True, include the abstract/summary column.

    Returns:
        A Rich Table.
    """
    table = Table(show_header=True, header_style="bold", show_lines=show_abstract)
    table.add_column("arXiv ID", style="dim", no_wrap=True)
    table.add_column("Year", justify="right", no_wrap=True)
    table.add_column("Category", no_wrap=True)
    table.add_column("Title")
    table.add_column("Authors", max_width=30)
    if show_abstract:
        table.add_column("Abstract")

    for paper in papers:
        if not paper:
            continue
        row = [
            paper.arxiv_id,
            _year_from_date(paper.published),
            paper.primary_category,
            paper.title,
            _format_authors(paper.authors),
        ]
        if show_abstract:
            row.append(paper.summary)
        table.add_row(*row)

    if isinstance(meta, PaperListMeta) and meta.total_results:
        total = meta.total_results
        start = meta.start_index
        count = meta.items_per_page or len(papers)
        table.caption = f"Showing {count} of {total} results (offset {start})"
        table.caption_style = "dim"
    elif isinstance(meta, dict) and meta.get("total_results"):
        total = meta.get("total_results", 0)
        start = meta.get("start_index", 0)
        count = meta.get("items_per_page", len(papers))
        table.caption = f"Showing {count} of {total} results (offset {start})"
        table.caption_style = "dim"

    return table


def format_paper_detail(
    paper: Paper,
) -> Panel:
    """Build a detailed single-paper view as a Rich Panel."""

    lines = Text()
    lines.append(paper.title, style="bold")
    lines.append("\n\n")

    # Authors
    if paper.authors:
        author_strs = []
        for a in paper.authors:
            if a.affiliation:
                author_strs.append(f"{a.name} ({a.affiliation})")
            else:
                author_strs.append(a.name)
        lines.append("Authors: ", style="bold")
        lines.append(", ".join(author_strs))
        lines.append("\n")

    # Dates
    lines.append("Published: ", style="bold")
    lines.append(paper.published)
    lines.append("\n")
    if paper.updated and paper.updated != paper.published:
        lines.append("Updated: ", style="bold")
        lines.append(paper.updated)
        lines.append("\n")

    # Categories
    lines.append("Categories: ", style="bold")
    cat_strs = []
    for c in paper.categories:
        if c == paper.primary_category:
            cat_strs.append(f"[{c}]")
        else:
            cat_strs.append(c)
    lines.append(" ".join(cat_strs))
    lines.append("\n")

    # Optional fields
    if paper.doi:
        lines.append("DOI: ", style="bold")
        lines.append(paper.doi)
        lines.append("\n")

    if paper.journal_ref:
        lines.append("Journal: ", style="bold")
        lines.append(paper.journal_ref)
        lines.append("\n")

    if paper.comment:
        lines.append("Comment: ", style="bold")
        lines.append(paper.comment)
        lines.append("\n")

    # Links
    lines.append("\n")
    lines.append("PDF: ", style="bold")
    lines.append(paper.pdf_url)
    lines.append("\n")
    lines.append("Abstract page: ", style="bold")
    lines.append(paper.abstract_url)
    lines.append("\n")

    # Abstract
    if paper.summary:
        lines.append("\n")
        lines.append("Abstract: ", style="bold")
        lines.append(paper.summary)

    return Panel(lines, title=f"arXiv:{paper.arxiv_id}", expand=False)
