"""Typed events emitted by the session stream."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Literal


@dataclass(slots=True)
class StatusUpdate:
    """Spinner / status bar change. ``None`` hides the spinner."""

    status: str | None
    thread_id: str | None = None


@dataclass(slots=True)
class TextDelta:
    """Incremental text chunk from the assistant."""

    text: str
    message_id: str
    thread_id: str | None = None


@dataclass(slots=True)
class TextComplete:
    """Flush signal — streaming for this message is done."""

    full_text: str
    message_id: str
    thread_id: str | None = None


@dataclass(slots=True)
class ToolCallStart:
    """A tool invocation has been detected."""

    tool_id: str
    tool_name: str
    args: dict[str, Any]
    thread_id: str | None = None


@dataclass(slots=True)
class ToolResult:
    """A tool has finished executing."""

    tool_id: str
    tool_name: str
    status: Literal["success", "error"]
    output: str
    diff: str | None = None
    diff_path: str | None = None
    thread_id: str | None = None


@dataclass(slots=True)
class ToolsApproved:
    """All pending tool calls were approved (manual or auto)."""

    thread_id: str | None = None


@dataclass(slots=True)
class ToolsRejected:
    """All pending tool calls were rejected by the user."""

    message: str = "Command rejected. Tell the agent what you'd like instead."
    thread_id: str | None = None


@dataclass(slots=True)
class AutoApproveEnabled:
    """User selected 'Auto-approve all' — session flag was set."""

    thread_id: str | None = None


@dataclass(slots=True)
class TokenUsage:
    """End-of-turn token usage report."""

    total_tokens: int
    thread_id: str | None = None


# Union of all possible events.
SessionEvent = (
    StatusUpdate
    | TextDelta
    | TextComplete
    | ToolCallStart
    | ToolResult
    | ToolsApproved
    | ToolsRejected
    | AutoApproveEnabled
    | TokenUsage
)

# SessionEvent class -> JSON "type" string.
# Single source of truth — used by both the engine and the sidecar protocol.
EVENT_TYPE_MAP: dict[type, str] = {
    StatusUpdate: "status_update",
    TextDelta: "text_delta",
    TextComplete: "text_complete",
    ToolCallStart: "tool_call_start",
    ToolResult: "tool_result",
    ToolsApproved: "tools_approved",
    ToolsRejected: "tools_rejected",
    AutoApproveEnabled: "auto_approve_enabled",
    TokenUsage: "token_usage",
}
