"""
Notification WebSocket message schemas.

Provides typed messages for real-time notifications including:
- New notification delivery
- Acknowledgment and read status
- Batch notifications
- Priority levels

Usage:
    from lightwave.schema.pydantic.contracts.websockets.notifications import (
        NotificationNewOutbound,
        NotificationAckInbound,
    )

    # Send notification
    notif = NotificationNewOutbound(
        id="notif-123",
        type="mention",
        title="You were mentioned",
        body="@john mentioned you in Call Sheet",
        action_url="/call-sheets/123",
        priority="high",
    )
    await websocket.send(notif.to_ws_json())
"""

from datetime import datetime
from typing import Any, Literal

from pydantic import Field

from lightwave.schema.pydantic.contracts.websockets.base import WSMessage

# =============================================================================
# Enums
# =============================================================================

NotificationType = Literal[
    "info",
    "success",
    "warning",
    "error",
    "mention",
    "invite",
    "update",
    "reminder",
    "approval",
    "comment",
    "assignment",
]

NotificationPriority = Literal["low", "normal", "high", "urgent"]


# =============================================================================
# Inbound Messages (Client -> Server)
# =============================================================================


class NotificationAckInbound(WSMessage):
    """
    Acknowledge notification received.

    Client sends this to confirm notification was delivered.
    """

    type: Literal["notification.ack"] = "notification.ack"
    notification_id: str = Field(..., description="Notification being acknowledged")


class NotificationDismissInbound(WSMessage):
    """
    Dismiss notification.

    Client sends this when user dismisses without reading.
    """

    type: Literal["notification.dismiss"] = "notification.dismiss"
    notification_id: str = Field(..., description="Notification to dismiss")


class NotificationMarkReadInbound(WSMessage):
    """
    Mark notification(s) as read.

    Client sends this when user reads notification(s).
    """

    type: Literal["notification.mark_read"] = "notification.mark_read"
    notification_ids: list[str] = Field(
        ...,
        min_length=1,
        description="Notifications to mark as read",
    )


# =============================================================================
# Outbound Messages (Server -> Client)
# =============================================================================


class NotificationAction(WSMessage):
    """Action button in a notification."""

    label: str = Field(..., description="Button label")
    url: str | None = Field(None, description="URL to navigate to")
    action: str | None = Field(None, description="Action identifier for callbacks")
    style: Literal["primary", "secondary", "danger"] = Field(
        "secondary",
        description="Button style",
    )


class NotificationNewOutbound(WSMessage):
    """
    New notification.

    Sent when a new notification is created for the user.
    """

    type: Literal["notification.new"] = "notification.new"
    id: str = Field(..., description="Notification ID")
    notification_type: NotificationType = Field(
        ...,
        alias="notificationType",
        description="Type of notification",
    )
    title: str = Field(..., max_length=200, description="Notification title")
    body: str | None = Field(None, max_length=1000, description="Notification body")
    action_url: str | None = Field(None, description="URL to navigate on click")
    actions: list[NotificationAction] | None = Field(
        None,
        description="Action buttons",
    )
    icon: str | None = Field(None, description="Icon identifier or URL")
    image_url: str | None = Field(None, description="Image to display")
    created_at: datetime = Field(
        default_factory=datetime.utcnow,
        description="When notification was created",
    )
    expires_at: datetime | None = Field(None, description="When notification expires")
    priority: NotificationPriority = Field("normal", description="Priority level")
    sound: bool = Field(True, description="Whether to play sound")
    vibrate: bool = Field(False, description="Whether to vibrate (mobile)")
    persistent: bool = Field(False, description="Whether notification persists")
    group: str | None = Field(None, description="Group ID for stacking")
    metadata: dict[str, Any] | None = Field(None, description="Additional data")


class NotificationUpdateOutbound(WSMessage):
    """
    Update existing notification.

    Sent when a notification's content or status changes.
    """

    type: Literal["notification.update"] = "notification.update"
    id: str = Field(..., description="Notification ID")
    title: str | None = Field(None, description="Updated title")
    body: str | None = Field(None, description="Updated body")
    priority: NotificationPriority | None = Field(None, description="Updated priority")
    expires_at: datetime | None = Field(None, description="Updated expiration")
    read: bool | None = Field(None, description="Read status")
    dismissed: bool | None = Field(None, description="Dismissed status")


class NotificationBatchOutbound(WSMessage):
    """
    Batch of notifications.

    Used for initial load or catching up after reconnect.
    """

    type: Literal["notification.batch"] = "notification.batch"
    notifications: list[NotificationNewOutbound] = Field(
        ...,
        description="List of notifications",
    )
    unread_count: int = Field(0, ge=0, description="Total unread count")
    has_more: bool = Field(False, description="Whether more notifications exist")
