"""Helpers for normalized workflow/UI event payloads."""
from __future__ import annotations

from datetime import UTC, datetime
from typing import Any
from uuid import uuid4

from logos_adk.types import ContentPart, Response, content_text, normalize_content_parts


def serialize_event_output(value: Any) -> Any:
    """Serialize workflow outputs into UI-friendly payloads."""
    if isinstance(value, Response):
        return {
            "content": value.content,
            "content_parts": [serialize_content_part(part) for part in normalize_content_parts(value.content_parts)],
            "status": value.status,
            "raw": dict(value.raw or {}),
        }
    if isinstance(value, ContentPart):
        return serialize_content_part(value)
    if isinstance(value, list):
        return [serialize_event_output(item) for item in value]
    if isinstance(value, dict):
        return {str(key): serialize_event_output(item) for key, item in value.items()}
    return value


def serialize_content_part(part: ContentPart) -> dict[str, Any]:
    return {
        "type": part.type,
        "text": part.text,
        "uri": part.uri,
        "data": part.data,
        "mime_type": part.mime_type,
        "name": part.name,
        "metadata": dict(part.metadata or {}),
    }


def event_output_text(value: Any) -> str | None:
    """Render an event payload into a short human-readable summary when possible."""
    if isinstance(value, Response):
        return content_text(value.content, value.content_parts)
    if isinstance(value, ContentPart):
        return content_text("", [value])
    if isinstance(value, dict):
        content = value.get("content")
        content_parts = value.get("content_parts")
        if isinstance(content, str) or isinstance(content_parts, list):
            try:
                return content_text(content if isinstance(content, str) else "", normalize_content_parts(content_parts))
            except Exception:
                pass
    if isinstance(value, str) and value.strip():
        return value.strip()
    return None


def _humanize_label(value: str | None) -> str:
    if not value:
        return "Текущий шаг"
    return value.replace("_", " ").replace("-", " ").strip().title()


def _default_user_facing(
    *,
    event: str,
    graph_name: str,
    node_name: str | None,
    status: str | None,
    summary: str | None,
) -> dict[str, Any]:
    if event == "graph_started":
        return {
            "kind": "run",
            "title": "Запускаем задачу",
            "detail": f"Подготавливаем выполнение { _humanize_label(graph_name) }",
            "step_key": "run:start",
            "status": "running",
            "visible": True,
        }
    if event == "node_started":
        label = _humanize_label(node_name)
        return {
            "kind": "step",
            "title": label,
            "detail": "Выполняем шаг",
            "step_key": f"step:{node_name or graph_name}",
            "status": "running",
            "visible": True,
        }
    if event == "node_completed":
        label = _humanize_label(node_name)
        if status == "paused":
            return {
                "kind": "needs_input",
                "title": label,
                "detail": summary or "Нужно ваше решение, чтобы продолжить",
                "step_key": f"step:{node_name or graph_name}",
                "status": "paused",
                "visible": True,
            }
        return {
            "kind": "step",
            "title": label,
            "detail": summary or "Шаг завершён",
            "step_key": f"step:{node_name or graph_name}",
            "status": "completed" if status not in {"failed", "error"} else "failed",
            "visible": True,
        }
    if event == "graph_completed":
        if status in {"failed", "error"}:
            return {
                "kind": "error",
                "title": "Не удалось завершить задачу",
                "detail": summary or "Во время выполнения произошла ошибка",
                "step_key": "run:result",
                "status": "failed",
                "visible": True,
            }
        return {
            "kind": "result",
            "title": "Результат готов",
            "detail": summary or "Задача завершена",
            "step_key": "run:result",
            "status": "completed",
            "visible": True,
        }
    if event in {"tool_started", "tool_completed", "node_progress"}:
        return {
            "kind": "trace",
            "title": _humanize_label(node_name),
            "detail": summary,
            "step_key": f"trace:{node_name or graph_name}",
            "status": "running",
            "visible": False,
        }
    return {
        "kind": "trace",
        "title": _humanize_label(node_name or graph_name),
        "detail": summary,
        "step_key": f"trace:{node_name or graph_name}",
        "status": status or "running",
        "visible": False,
    }


def make_ui_event(
    *,
    event: str,
    event_type: str,
    graph_name: str,
    graph_run_id: str,
    sequence: int,
    session_id: str | None = None,
    correlation_id: str | None = None,
    trace_id: str | None = None,
    node_name: str | None = None,
    parent_event_id: str | None = None,
    route_source: str | None = None,
    route_target: str | None = None,
    edge_label: str | None = None,
    status: str | None = None,
    duration_ms: float | None = None,
    output: Any = None,
    metadata: dict[str, Any] | None = None,
    topic: str | None = None,
    publisher: str | None = None,
    payload_summary: str | None = None,
) -> dict[str, Any]:
    """Build a normalized UI event payload compatible with dashboard graph events."""
    event_output = serialize_event_output(output)
    summary = payload_summary or event_output_text(output)
    user_facing = dict((metadata or {}).get("user_facing") or {})
    if not user_facing:
        user_facing = _default_user_facing(
            event=event,
            graph_name=graph_name,
            node_name=node_name,
            status=status,
            summary=summary,
        )
    return {
        "event_id": uuid4().hex,
        "parent_event_id": parent_event_id,
        "event": event,
        "event_type": event_type,
        "graph_name": graph_name,
        "graph_run_id": graph_run_id,
        "pipeline_id": graph_run_id,
        "trace_id": trace_id,
        "session_id": session_id,
        "correlation_id": correlation_id,
        "sequence": sequence,
        "timestamp": datetime.now(UTC).isoformat(),
        "node_name": node_name,
        "route_source": route_source,
        "route_target": route_target,
        "edge_label": edge_label,
        "status": status,
        "duration_ms": duration_ms,
        "output": event_output,
        "metadata": dict(metadata or {}),
        "user_facing": user_facing,
        "topic": topic,
        "publisher": publisher,
        "payload_summary": summary,
    }


__all__ = [
    "event_output_text",
    "make_ui_event",
    "serialize_content_part",
    "serialize_event_output",
]
