"""
Event data models for event stream.
"""

from enum import Enum
from typing import Any, Optional

from pydantic import BaseModel, Field


class EventType(str, Enum):
    """Types of events that can be emitted."""

    DEVICE_FOUND = "device_found"
    DEVICE_CONNECTED = "device_connected"
    DEVICE_DISCONNECTED = "device_disconnected"
    NOTIFICATION = "notification"
    ERROR = "error"


class BaseEvent(BaseModel):
    """Base class for all events."""

    type: EventType = Field(..., description="Event type")
    timestamp: float = Field(..., description="Event timestamp (Unix epoch)")

    model_config = {"populate_by_name": True}


class DeviceFoundEvent(BaseEvent):
    """Event emitted when a device is found during scanning."""

    type: EventType = EventType.DEVICE_FOUND
    device_address: str = Field(..., description="Device Bluetooth address")
    device_name: Optional[str] = Field(None, description="Device name")
    rssi: int = Field(..., description="Signal strength")
    service_uuids: list[str] = Field(default_factory=list, description="Service UUIDs")


class DeviceConnectedEvent(BaseEvent):
    """Event emitted when a device is connected."""

    type: EventType = EventType.DEVICE_CONNECTED
    device_address: str = Field(..., description="Device Bluetooth address")
    device_name: Optional[str] = Field(None, description="Device name")


class DeviceDisconnectedEvent(BaseEvent):
    """Event emitted when a device is disconnected."""

    type: EventType = EventType.DEVICE_DISCONNECTED
    device_address: str = Field(..., description="Device Bluetooth address")
    reason: Optional[str] = Field(None, description="Disconnection reason")


class NotificationEvent(BaseEvent):
    """Event emitted when a characteristic notification is received."""

    type: EventType = EventType.NOTIFICATION
    device_address: str = Field(..., description="Device Bluetooth address")
    characteristic_uuid: str = Field(..., description="Characteristic UUID")
    data: str = Field(..., description="Data received (base64 encoded)")
    handle: Optional[int] = Field(None, description="Characteristic handle")


class ErrorEvent(BaseEvent):
    """Event emitted when an error occurs."""

    type: EventType = EventType.ERROR
    device_address: Optional[str] = Field(None, description="Related device address")
    error_code: Optional[str] = Field(None, description="Error code")
    message: str = Field(..., description="Error message")
    details: Optional[dict[str, Any]] = Field(None, description="Additional error details")
