"""Presenter for content list command output."""

import json
from datetime import datetime
from typing import Any

from alloy_runtime_types.dtos.content import ListContentPartsResponse
from alloy_runtime_types.dtos.templates import TagResponse

from cli.infrastructure.output import OutputService
from cli.infrastructure.renderers.list_renderer import ColumnConfig


def _format_tags(tags: list[TagResponse]) -> str:
    """Format tags for display, truncating if too many.

    Args:
        tags: List of tag responses

    Returns:
        Formatted tags string
    """
    if not tags:
        return "-"
    return ", ".join(t.tag_path for t in tags)


def _format_content_preview(
    content_text: str | None, content_structured: dict[str, Any] | None
) -> str:
    """Format content preview, truncating long content.

    Args:
        content_text: Plain text content
        content_structured: Structured JSON content

    Returns:
        Truncated content preview string
    """
    if content_text:
        text = content_text.replace("\n", " ").strip()
        return text

    if content_structured:
        try:
            return json.dumps(content_structured, ensure_ascii=False)
        except (TypeError, ValueError):
            return str(content_structured)

    return "-"


def _format_model_info(part: Any) -> str:
    """Format model/provider information from execution metadata.

    Args:
        part: Content part item response

    Returns:
        Formatted model info string
    """
    if not part.execution_metadata:
        return "-"

    provider = part.execution_metadata.provider_key or ""
    model = part.execution_metadata.provider_model_name or ""

    if provider and model:
        return f"{provider}/{model}"
    elif model:
        return model
    elif provider:
        return provider
    return "-"


def _format_role(part: Any) -> str:
    """Format the message role for display."""
    return str(part.message_role)


def _format_created_at(created_at: datetime | None) -> str:
    """Format creation timestamp for display.

    Args:
        created_at: Creation timestamp

    Returns:
        Formatted date string
    """
    if not created_at:
        return "-"
    return created_at.strftime("%Y-%m-%d %H:%M")


def present_content_list(response: ListContentPartsResponse) -> None:
    """Present list of content parts with Rich table formatting.

    Args:
        response: List content parts response from server
    """
    output = OutputService.get()

    # Define table columns with compact layout configuration
    # Line 1 (primary): ID, type, model, created - machine-readable data
    # Line 2 (detail): Content preview, tags - human-readable content
    columns = [
        ColumnConfig(
            source_field="id",
            header_label="ID",
            compact_line=1,
            compact_style="cyan",
        ),
        ColumnConfig(
            source_field="_role",
            header_label="Role",
            compact_line=1,
            compact_style="yellow",
        ),
        ColumnConfig(
            source_field="content_type_id",
            header_label="Type",
            compact_line=1,
            compact_style="magenta",
        ),
        ColumnConfig(
            source_field="_model_info",
            header_label="Model",
            compact_line=1,
            compact_style="green",
        ),
        ColumnConfig(
            source_field="created_at",
            header_label="Created",
            formatter=_format_created_at,
            compact_line=1,
            compact_style="blue",
        ),
        ColumnConfig(
            source_field="_content_preview",
            header_label="Content",
            compact_line=2,
            compact_style="dim",
        ),
        ColumnConfig(
            source_field="tags",
            header_label="Tags",
            formatter=_format_tags,
            compact_line=2,
            compact_style="dim italic",
        ),
    ]

    # Pre-process items to add computed fields
    # We need to create wrapper objects with the computed fields
    class ContentPartWrapper:
        """Wrapper to add computed fields for table rendering."""

        def __init__(self, part: Any):
            self._part = part
            # Copy all original fields
            self.id = part.id
            self.content_type_id = part.content_type_id
            self.tags = part.tags
            self.created_at = part.created_at
            # Add computed fields
            self._role = _format_role(part)
            self._content_preview = _format_content_preview(
                part.content_text, part.content_structured
            )
            self._model_info = _format_model_info(part)

    wrapped_items = [ContentPartWrapper(part) for part in response.content_parts]

    # Render table
    output.table(
        items=wrapped_items,  # type: ignore[arg-type]
        title=f"Content Parts ({response.total_count})",
        columns=columns,
        raw_payload=response,
        cursor=response.cursor,
        total_count=response.total_count,
    )
