"""Per-provider typed device config hierarchy.

Each provider owns its config subclass. Device.to_config() is the single place
that maps the flat Device storage model to the right typed config.
"""

from dataclasses import dataclass, field
from typing import List, Literal, Optional, Union


@dataclass(frozen=True)
class BaseDeviceConfig:
    device_id: str
    device_url: str
    led_count: int
    software_brightness: int = 255
    test_mode_active: bool = False
    auto_shutdown: bool = False
    rgbw: bool = False


@dataclass(frozen=True)
class WLEDConfig(BaseDeviceConfig):
    device_type: Literal["wled"] = "wled"
    use_ddp: bool = False


@dataclass(frozen=True)
class AdalightConfig(BaseDeviceConfig):
    device_type: Literal["adalight"] = "adalight"
    baud_rate: Optional[int] = None


@dataclass(frozen=True)
class AmbiLEDConfig(BaseDeviceConfig):
    device_type: Literal["ambiled"] = "ambiled"
    baud_rate: Optional[int] = None


@dataclass(frozen=True)
class DMXConfig(BaseDeviceConfig):
    device_type: Literal["dmx"] = "dmx"
    dmx_protocol: str = "artnet"
    dmx_start_universe: int = 0
    dmx_start_channel: int = 1


@dataclass(frozen=True)
class ESPNowConfig(BaseDeviceConfig):
    device_type: Literal["espnow"] = "espnow"
    baud_rate: Optional[int] = None
    espnow_peer_mac: str = ""
    espnow_channel: int = 1


@dataclass(frozen=True)
class HueConfig(BaseDeviceConfig):
    device_type: Literal["hue"] = "hue"
    hue_username: str = ""
    hue_client_key: str = ""
    hue_entertainment_group_id: str = ""


@dataclass(frozen=True)
class SPIConfig(BaseDeviceConfig):
    device_type: Literal["spi"] = "spi"
    spi_speed_hz: int = 800000
    spi_led_type: str = "WS2812B"


@dataclass(frozen=True)
class ChromaConfig(BaseDeviceConfig):
    device_type: Literal["chroma"] = "chroma"
    chroma_device_type: str = "chromalink"


@dataclass(frozen=True)
class GameSenseConfig(BaseDeviceConfig):
    device_type: Literal["gamesense"] = "gamesense"
    gamesense_device_type: str = "keyboard"


@dataclass(frozen=True)
class BLEConfig(BaseDeviceConfig):
    device_type: Literal["ble"] = "ble"
    ble_family: str = ""
    ble_govee_key: str = ""


@dataclass(frozen=True)
class GroupConfig(BaseDeviceConfig):
    device_type: Literal["group"] = "group"
    group_mode: str = "sequence"
    group_device_ids: List[str] = field(default_factory=list)


@dataclass(frozen=True)
class OpenRGBConfig(BaseDeviceConfig):
    device_type: Literal["openrgb"] = "openrgb"
    zone_mode: str = "combined"


@dataclass(frozen=True)
class MockConfig(BaseDeviceConfig):
    device_type: Literal["mock"] = "mock"
    send_latency_ms: int = 0


@dataclass(frozen=True)
class DemoConfig(BaseDeviceConfig):
    device_type: Literal["demo"] = "demo"
    send_latency_ms: int = 0


@dataclass(frozen=True)
class MQTTConfig(BaseDeviceConfig):
    device_type: Literal["mqtt"] = "mqtt"


@dataclass(frozen=True)
class WSConfig(BaseDeviceConfig):
    device_type: Literal["ws"] = "ws"


@dataclass(frozen=True)
class USBHIDConfig(BaseDeviceConfig):
    device_type: Literal["usbhid"] = "usbhid"


DeviceConfig = Union[
    WLEDConfig,
    AdalightConfig,
    AmbiLEDConfig,
    DMXConfig,
    ESPNowConfig,
    HueConfig,
    SPIConfig,
    ChromaConfig,
    GameSenseConfig,
    BLEConfig,
    GroupConfig,
    MQTTConfig,
    WSConfig,
    USBHIDConfig,
    OpenRGBConfig,
    MockConfig,
    DemoConfig,
]
