"""Event conversion utilities for converting between backend and frontend formats."""

import json

from yera.events.models.in_event import InputEvent
from yera.events.models.out_event import OutputEvent


def output_event_to_json(event: OutputEvent) -> dict:
    """Convert an OutputEvent to frontend JSON format.

    Args:
        event: OutputEvent from the agent execution

    Returns:
        Dictionary matching the frontend AgentMessage interface:
        {
            "message_type": "informational" | "await_user" | "await_agent" | "layout",
            "block_type": str,
            "block_id": str,
            "data": dict,
            "timestamp": str (ISO format),
            "chunk_id": int,
            "agent": {
                "name": str,
                "instance_id": int
            },
            "parent_block_id": str | None
        }
    """
    # Convert agent_instance to frontend format
    agent = {
        "name": event.agent_instance.agent_id,
        "instance_id": event.agent_instance.instance_id,
    }

    # Serialize data field (Pydantic models have model_dump())
    # Use mode='json' to ensure date/datetime objects are serialized to strings
    if hasattr(event.data, "model_dump"):
        data = event.data.model_dump(mode="json")
    else:
        # Fallback for non-Pydantic data
        data = event.data

    return {
        "message_type": event.message_type,
        "block_type": event.block_type,
        "block_id": event.block_id,
        "data": data,
        "timestamp": event.timestamp.isoformat(),
        "chunk_id": event.chunk_id,
        "agent": agent,
        "parent_block_id": event.parent_block_id,
    }


def user_interaction_to_input_event(interaction: dict) -> InputEvent:
    """Convert a UserInteraction dict to InputEvent format.

    Args:
        interaction: UserInteraction dictionary with:
            - blockId: str
            - value: Any
            - blockType: str

    Returns:
        InputEvent for pushing to EventStream
    """
    # Convert interaction value to string
    # For buttons, value is typically the button text
    # For text inputs, value is the text string
    # For other types, convert to JSON string
    if isinstance(interaction["value"], str):
        value_str = interaction["value"]
    else:
        value_str = json.dumps(interaction["value"])

    # Use blockId as identifier, blockType as type
    return InputEvent(
        identifier=interaction["blockId"],
        type=interaction["blockType"],
        data=value_str,
    )
