"""Presenter for template get command output."""

import pyperclip
from typing import Any, cast

from pydantic import BaseModel

from cli.infrastructure.formatting.fields import (
    format_datetime,
)
from cli.infrastructure.output import OutputFormat, OutputService
from cli.infrastructure.renderers.entity_renderer import FieldConfig
from cli.infrastructure.renderers.list_renderer import ColumnConfig
from alloy_runtime_types.dtos.templates import (
    GetTemplateResponse,
    TagResponse,
    TemplateDependencyResponse,
    TemplateVersionResponse,
)


def _format_tags(tags: list[TagResponse]) -> str:
    """Format tags for display.

    Args:
        tags: List of tag responses

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


def _format_dependencies(dependencies: list[TemplateDependencyResponse]) -> str:
    """Format dependencies for display.

    Args:
        dependencies: List of dependency responses

    Returns:
        Formatted dependencies string or "(none)" if empty
    """
    if not dependencies:
        return "(none)"
    return ", ".join(d.child_template_name for d in dependencies)


def _format_variables(variables: list[str]) -> str:
    """Format required variables for display.

    Args:
        variables: List of variable names

    Returns:
        Formatted variables string or "(none)" if empty
    """
    if not variables:
        return "(none)"
    return ", ".join(variables)


def _truncate_content(content: str, max_length: int = 500) -> str:
    """Truncate content for preview display.

    Args:
        content: Content string to truncate
        max_length: Maximum length before truncation

    Returns:
        Truncated content with indicator if truncated
    """
    _ = max_length
    return content


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


def _format_content_length(content: str) -> str:
    return f"{len(content)} chars"


def _copy_to_clipboard(content: str, template_name: str, output: OutputService) -> bool:
    try:
        pyperclip.copy(content)
        output.result(
            action="copy",
            resource="template",
            status="success",
            identifier=None,
            name=template_name,
            extra_fields={
                "Destination": "clipboard",
                "Characters": len(content),
            },
        )
        return True
    except pyperclip.PyperclipException as e:
        output.result(
            action="copy",
            resource="template",
            status="failed",
            identifier=None,
            name=template_name,
            extra_fields={
                "Destination": "clipboard",
                "Reason": str(e),
            },
        )
        return False


def present_template_details(
    response: GetTemplateResponse, full: bool = False, copy: bool = False
) -> None:
    output = OutputService.get()
    template = response.template
    versions = response.versions
    dependencies = response.dependencies

    # Find latest version for required variables
    latest_version = next((v for v in versions if v.is_latest), None)
    required_variables = latest_version.required_variables if latest_version else []

    if getattr(output, "format", OutputFormat.COMPACT) == OutputFormat.JSON:
        if copy and latest_version and latest_version.content:
            _copy_to_clipboard(latest_version.content, template.name, output)
        output.raw(response)
        return

    metadata_fields = [
        FieldConfig("id", "ID", str),
        FieldConfig("name", "Name"),
        FieldConfig("content_type_id", "Content Type"),
        FieldConfig("visibility_id", "Visibility"),
        FieldConfig("description", "Description"),
        FieldConfig("tags", "Tags", _format_tags),
        FieldConfig("id", "Dependencies", lambda _: _format_dependencies(dependencies)),
        FieldConfig(
            "id",
            "Required Variables",
            lambda _: _format_variables(required_variables),
        ),
        FieldConfig("organization_id", "Organization ID", _format_optional_uuid),
        FieldConfig("user_id", "User ID", _format_optional_uuid),
        FieldConfig("created_at", "Created At", format_datetime),
        FieldConfig("updated_at", "Updated At", format_datetime),
    ]

    output.entity(
        template,
        f"Template: {template.name}",
        metadata_fields,
        raw_payload=response,
    )

    if versions:
        _present_versions_table(output, versions)

    if latest_version and latest_version.content:
        content = latest_version.content

        if copy:
            _copy_to_clipboard(content, template.name, output)

        if full:
            _present_content(output, template.name, latest_version, full=True)
        else:
            _present_content(output, template.name, latest_version, full=False)


def _present_versions_table(
    output: OutputService, versions: list[TemplateVersionResponse]
) -> None:
    columns = [
        ColumnConfig("version", "Version", lambda value: f"v{value}"),
        ColumnConfig("is_latest", "Latest"),
        ColumnConfig("content", "Content Length", _format_content_length),
        ColumnConfig("required_variables", "Variables", _format_variables),
        ColumnConfig("created_at", "Created At", format_datetime),
    ]

    output.table(
        items=cast(list[BaseModel], versions),
        title=f"Versions ({len(versions)})",
        columns=columns,
    )


def _present_content(
    output: OutputService,
    template_name: str,
    version: TemplateVersionResponse,
    *,
    full: bool,
) -> None:
    content_fields = [
        FieldConfig("version", "Version", lambda value: f"v{value}"),
        FieldConfig("content", "Characters", _format_content_length),
        FieldConfig(
            "content",
            "Content",
            None if full else _truncate_content,
        ),
    ]

    title = f"Content: {template_name}" if full else f"Content Preview: {template_name}"
    output.entity(version, title, content_fields)
