"""List renderer for displaying collections with pagination.

Renders lists of Pydantic model instances using configured column formatters.
"""

from collections.abc import Sequence
from dataclasses import dataclass
from typing import Any, Callable

from pydantic import BaseModel

from cli.infrastructure.console import get_console
from cli.infrastructure.formatters.base import ColumnAlignment, ColumnMeta, Formatter


@dataclass
class ColumnConfig:
    """Configuration for a table column.

    Attributes:
        source_field: Attribute name on the Pydantic model
        header_label: Column header text
        formatter: Optional function to format the column value
        width: Optional fixed column width
        align: Text alignment - "left", "center", or "right"
        compact_line: For compact format - 1 = primary line (metadata),
                      2 = detail line (content/description). Default is 1.
        compact_style: Rich style for compact format (e.g., "cyan bold", "dim")
    """

    source_field: str
    header_label: str
    formatter: Callable[[Any], str] | None = None
    width: int | None = None
    align: ColumnAlignment = "left"
    compact_line: int = 1
    compact_style: str | None = None


class ListRenderer:
    """Renders lists/collections with pagination support.

    Extracts data from lists of Pydantic models according to column configurations
    and renders using the provided formatter.
    """

    def __init__(self, formatter: Formatter):
        """Initialize renderer with a formatter.

        Args:
            formatter: Formatter instance (CompactFormatter, JsonFormatter, etc.)
        """
        self.formatter = formatter

    def render(
        self,
        items: Sequence[BaseModel],
        columns: list[ColumnConfig],
        title: str | None = None,
        cursor: str | None = None,
        total_count: int | None = None,
    ) -> None:
        """Render paginated list to console.

        Args:
            items: Sequence of Pydantic model instances to render
            columns: Column configurations defining what to show
            title: Optional table title
            cursor: Pagination cursor for next page
            total_count: Total items across all pages
        """
        # Extract data from items using column configs
        rows: list[dict[str, Any]] = []
        for item in items:
            row: dict[str, Any] = {}
            for col in columns:
                value = getattr(item, col.source_field, None)

                if col.formatter:
                    value = col.formatter(value)

                row[col.header_label] = value
            rows.append(row)

        column_meta = [
            ColumnMeta(
                label=col.header_label,
                compact_line=col.compact_line,
                compact_style=col.compact_style,
                width=col.width,
                align=col.align,
            )
            for col in columns
        ]

        del title
        output = self.formatter.format_list(rows, None, column_meta)

        console = get_console()
        if isinstance(output, str):
            console.file.write(f"{output}\n")
            console.file.flush()
        elif items:
            console.print(output)
        else:
            console.print("(0 rows)", markup=False, highlight=False)

        if cursor:
            console.print(f"Next page cursor: {cursor}", markup=False, highlight=False)
        if total_count is not None:
            console.print(
                f"Showing {len(items)} of {total_count} total",
                markup=False,
                highlight=False,
            )
