"""Typed domain event envelope for SSE streaming.

Every emitted event wraps mutation results in a canonical shape so both
backend subscribers and frontend consumers have a single contract to parse.
"""

from datetime import UTC, datetime
from enum import StrEnum
from typing import Any

from pydantic import BaseModel, Field


class EventType(StrEnum):
    """Exhaustive list of domain event types pushed over SSE."""

    # Reservation events
    reservation_created = "reservation_created"
    reservation_updated = "reservation_updated"
    reservation_status_changed = "reservation_status_changed"
    reservation_cancelled = "reservation_cancelled"

    # Order events
    order_created = "order_created"
    order_status_changed = "order_status_changed"
    order_cancelled = "order_cancelled"

    # Customer events
    customer_updated = "customer_updated"
    customer_visit_recorded = "customer_visit_recorded"
    customer_noshow_recorded = "customer_noshow_recorded"

    # WhatsApp events
    template_status_changed = "template_status_changed"


class DomainEvent(BaseModel):
    """Canonical event envelope published to Redis and streamed over SSE."""

    type: EventType
    restaurant_id: str
    entity_id: str
    occurred_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
    payload: dict[str, Any] = Field(default_factory=dict)


# Redis channel used for all domain event fan-out.
DOMAIN_EVENTS_CHANNEL = "domain_events"
