"""Presenter for synthesis list output."""

from datetime import datetime
from typing import Any, cast

from pydantic import BaseModel
from alloy_runtime_types.dtos.knowledge import ListSynthesesResponse, SynthesisSummary
from cli.infrastructure.formatting.fields import format_datetime, format_uuid
from cli.infrastructure.output import OutputService
from cli.infrastructure.renderers.list_renderer import ColumnConfig


def _format_stale(value: bool) -> str:
    return "stale" if value else "current"


def _format_collections(value: list[Any]) -> Any:
    if not value:
        return cast(str, None)
    return ", ".join(str(collection_id) for collection_id in value)


def _latest_heartbeat_at(synthesis: SynthesisSummary) -> datetime | None:
    queue_metadata = synthesis.queue_metadata
    if queue_metadata is None:
        return None
    if isinstance(queue_metadata, dict):
        queue_metadata_dict = cast(dict[str, Any], queue_metadata)
        latest_heartbeat = queue_metadata_dict.get("last_heartbeat_at")
        if isinstance(latest_heartbeat, datetime):
            return latest_heartbeat
        return None
    return queue_metadata.last_heartbeat_at


def _format_heartbeat(synthesis: SynthesisSummary) -> str:
    if synthesis.status in {"accepted", "queued"}:
        return "pending"
    if synthesis.status in {"worker_assigned", "processing"}:
        return "active" if _latest_heartbeat_at(synthesis) is not None else "missing"
    return "stopped"


class SynthesisListRow(BaseModel):
    id: Any
    title: str
    status: str
    heartbeat: str
    latest_heartbeat_at: datetime | None
    is_stale: bool
    source_chunk_count: int
    collection_ids: list[Any]
    created_at: datetime


def present_syntheses_list(response: ListSynthesesResponse) -> None:
    rows = [
        SynthesisListRow(
            id=synthesis.id,
            title=synthesis.title,
            status=synthesis.status,
            heartbeat=_format_heartbeat(synthesis),
            latest_heartbeat_at=_latest_heartbeat_at(synthesis),
            is_stale=synthesis.is_stale,
            source_chunk_count=synthesis.source_chunk_count,
            collection_ids=synthesis.collection_ids,
            created_at=synthesis.created_at,
        )
        for synthesis in response.syntheses
    ]
    items = cast(list[BaseModel], rows)
    OutputService.get().table(
        items,
        f"Syntheses ({response.total})",
        [
            ColumnConfig("id", "ID", lambda value: format_uuid(value, short=True)),
            ColumnConfig("title", "Title"),
            ColumnConfig("status", "Status"),
            ColumnConfig("heartbeat", "Heartbeat"),
            ColumnConfig("latest_heartbeat_at", "Latest Heartbeat", format_datetime),
            ColumnConfig("is_stale", "Stale", _format_stale),
            ColumnConfig("source_chunk_count", "Sources"),
            ColumnConfig("collection_ids", "Collections", _format_collections),
            ColumnConfig("created_at", "Created", format_datetime),
        ],
        raw_payload=response,
    )
