"""Issue message model for the Connexity SDK.

This module defines `IssueMessage`, a lightweight data container used to record
issues and noteworthy issues across the pipeline (transport, services, tools,
etc.).

The model is intentionally simple and serializable via `to_dict()`.
"""

from __future__ import annotations

import uuid
from enum import Enum
from typing import Any, Literal

IssueSource = Literal[
    "transport",
    "frame_filter",
    "observer",
    "frame_processor",
    "frame_serializer",
    "switcher",
    "llm_service",
    "tts_service",
    "stt_service",
    "tool_call",
    "unknown",
]


class IssueCode(str, Enum):
    """Enumeration of supported issue codes.

    These codes represent standardized issue types that can be detected
    and reported by the SDK or backend systems.
    """

    # Unauthorized Commitment
    UAC = "UAC"
    # Regulatory Compliance Violation
    RCV = "RCV"
    # Incorrect Critical Information
    ICI = "ICI"
    # Wrong Tool Usage
    WTU = "WTU"
    # Incorrect Tool Parameters
    ITP = "ITP"
    # Repeated Tool Calls
    RTC = "RTC"
    # Unresponsive Agent
    UAR = "UAR"
    # Latency Peak
    LTP = "LTP"
    # Core Component Failure
    CCF = "CCF"
    # Tool Call Failure
    TCF = "TCF"
    # Interruption Failure
    ITF = "ITF"
    # Interruption Loop
    ILF = "ILF"
    # Duplicate Output
    DUP = "DUP"
    # TTS Output Prolongation
    TTS_P = "TTS_P"
    # TTS Hallucinated Speech
    TTS_H = "TTS_H"


class IssueMessage:
    """Represents a single issue observed during a call session.

    Args:
        code: Machine-readable issue code (from IssueCode enum).
        title: Short, human-readable title (Capital Case, <= 6 words).
        description: Detailed description of the issue (may include error
            messages, tracebacks, etc.).
        source: Component that produced the issue.
        message_id: Optional upstream message identifier (if the issue pertains
            to a specific message).
        seconds_from_start: Optional timestamp offset from the start of the
            session.
        metadata: Optional extra structured context.

    Attributes:
        id: Unique identifier for this issue message.
        code: Machine-readable issue code.
        title: Short, human-readable title.
        description: Detailed description of the issue.
        source: Component that produced the issue.
        message_id: Optional upstream message identifier.
        seconds_from_start: Optional timestamp offset from session start.
        metadata: Extra structured context.
    """

    def __init__(
        self,
        code: IssueCode,
        title: str,
        description: str,
        source: IssueSource,
        message_id: str | None = None,
        seconds_from_start: float | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> None:
        self.code: IssueCode = code
        self.title: str = title
        self.description: str = description

        # Use a regular UUID for the issue message id.
        self.id: uuid.UUID = uuid.uuid4()
        self.message_id: str | None = message_id
        self.source: IssueSource = source
        self.seconds_from_start: float | None = seconds_from_start
        self.metadata: dict[str, Any] = metadata or {}

    def to_dict(self) -> dict[str, Any]:
        """Serialize the issue message to a JSON-friendly dict.

        Returns:
            Dictionary representation of this issue.
        """
        return {
            "id": str(self.id),
            "code": self.code.value,
            "title": self.title,
            "description": self.description,
            "source": self.source,
            "seconds_from_start": self.seconds_from_start,
            "metadata": self.metadata,
            "message_id": self.message_id,
        }
