"""Presenters for pipeline executions command output."""

import json
from typing import Any, cast

from pydantic import BaseModel

from alloy_runtime_types.dtos.pipeline import (
    GetPipelineExecutionResponse,
    ListPipelineExecutionsResponse,
    PipelineExecutionDetail,
)

from cli.infrastructure.formatting.fields import format_datetime
from cli.infrastructure.output import OutputService
from cli.infrastructure.renderers.entity_renderer import FieldConfig
from cli.infrastructure.renderers.list_renderer import ColumnConfig


def _format_status(status: str) -> str:
    """Format status with color hints."""
    return status


def _format_duration(duration_ms: int | None) -> Any:
    """Format duration in human-readable format."""
    if duration_ms is None:
        return cast(str, None)
    if duration_ms < 1000:
        return f"{duration_ms}ms"
    return f"{duration_ms / 1000:.1f}s"


def _format_optional_datetime(value: Any) -> Any:
    if value is None:
        return cast(str, None)
    return format_datetime(value)


def _format_optional_uuid(value: Any) -> Any:
    if value is None:
        return cast(str, None)
    return str(value)


def _format_json_block(value: dict[str, object] | None) -> Any:
    if value is None:
        return cast(str, None)
    return json.dumps(value, indent=2, sort_keys=True)


def present_executions_list(response: ListPipelineExecutionsResponse) -> None:
    """Present list of executions with Rich table formatting."""
    output = OutputService.get()

    columns = [
        ColumnConfig(
            source_field="id",
            header_label="ID",
            compact_line=1,
            compact_style="cyan",
        ),
        ColumnConfig(
            source_field="status",
            header_label="Status",
            formatter=_format_status,
            compact_line=1,
            compact_style="yellow",
        ),
        ColumnConfig(
            source_field="total_duration_ms",
            header_label="Duration",
            formatter=_format_duration,
            compact_line=1,
            compact_style="green",
        ),
        ColumnConfig(
            source_field="queued_at",
            header_label="Queued",
            formatter=_format_optional_datetime,
            compact_line=2,
            compact_style="blue",
        ),
        ColumnConfig(
            source_field="external_id",
            header_label="External ID",
            formatter=lambda x: x if x else cast(str, None),
            compact_line=2,
            compact_style="dim",
        ),
    ]

    output.table(
        items=cast(list[BaseModel], response.executions),
        title=f"Executions ({response.total})",
        columns=columns,
        raw_payload=response,
    )


def _format_tags_from_execution(execution: PipelineExecutionDetail) -> str:
    """Format tags for display."""
    if not execution.tags:
        return "[]"
    return ", ".join(t.tag_path for t in execution.tags)


def present_execution_detail(
    response: GetPipelineExecutionResponse, *, print_logs: bool = False
) -> None:
    """Present execution details with Rich formatting."""
    output = OutputService.get()
    execution = response.execution

    fields = [
        FieldConfig("id", "Execution ID", str),
        FieldConfig("pipeline_definition_id", "Pipeline ID", _format_optional_uuid),
        FieldConfig("status", "Status"),
        FieldConfig("external_id", "External ID"),
        FieldConfig("queued_at", "Queued At", format_datetime),
        FieldConfig("started_at", "Started At", _format_optional_datetime),
        FieldConfig("completed_at", "Completed At", _format_optional_datetime),
        FieldConfig("total_duration_ms", "Duration", lambda v: _format_duration(v)),
        FieldConfig("error_message", "Error"),
        FieldConfig("tags", "Tags", lambda _: _format_tags_from_execution(execution)),
    ]

    if execution.result_data is not None:
        fields.append(FieldConfig("result_data", "Result Data", _format_json_block))

    if print_logs and execution.execution_stdout is not None:
        fields.append(FieldConfig("execution_stdout", "Stdout"))

    if print_logs and execution.execution_stderr is not None:
        fields.append(FieldConfig("execution_stderr", "Stderr"))

    output.entity(
        execution,
        f"Execution: {execution.status}",
        fields,
        raw_payload=response,
    )
