"""Demo device provider — virtual LED devices for demo mode."""

from datetime import datetime, timezone
from typing import List

from wled_controller.config import is_demo_mode
from wled_controller.core.devices.led_client import (
    DeviceHealth,
    DiscoveredDevice,
    LEDClient,
    LEDDeviceProvider,
)
from wled_controller.core.devices.mock_client import MockClient

# Pre-defined virtual devices: (name, led_count, ip, width, height)
_DEMO_DEVICES = [
    ("Demo LED Strip", 60, "demo-strip", None, None),
    ("Demo LED Matrix", 256, "demo-matrix", 16, 16),
    ("Demo LED Ring", 24, "demo-ring", None, None),
]


class DemoDeviceProvider(LEDDeviceProvider):
    """Provider for virtual demo LED devices.

    Exposes three discoverable virtual devices when demo mode is active.
    Uses MockClient for actual LED output (pixels are silently discarded).
    """

    @property
    def device_type(self) -> str:
        return "demo"

    @property
    def capabilities(self) -> set:
        return {"manual_led_count", "power_control", "brightness_control", "static_color"}

    def create_client(self, url: str, **kwargs) -> LEDClient:
        return MockClient(
            url,
            led_count=kwargs.get("led_count", 0),
            send_latency_ms=kwargs.get("send_latency_ms", 0),
        )

    async def check_health(self, url: str, http_client, prev_health=None) -> DeviceHealth:
        # Simulate ~2ms latency for realistic appearance
        return DeviceHealth(
            online=True,
            latency_ms=2.0,
            last_checked=datetime.now(timezone.utc),
            device_name=url,
            device_version="demo",
        )

    async def validate_device(self, url: str) -> dict:
        # Look up configured LED count from demo devices
        for name, led_count, ip, _w, _h in _DEMO_DEVICES:
            if url == f"demo://{ip}":
                return {"led_count": led_count}
        # Fallback for unknown demo URLs
        return {"led_count": 60}

    async def discover(self, timeout: float = 3.0) -> List[DiscoveredDevice]:
        if not is_demo_mode():
            return []

        return [
            DiscoveredDevice(
                name=name,
                url=f"demo://{ip}",
                device_type="demo",
                ip=ip,
                mac=f"DE:MO:00:00:00:{i:02X}",
                led_count=led_count,
                version="demo",
            )
            for i, (name, led_count, ip, _w, _h) in enumerate(_DEMO_DEVICES)
        ]

    async def get_power(self, url: str, **kwargs) -> bool:
        return True

    async def set_power(self, url: str, on: bool, **kwargs) -> None:
        pass

    async def get_brightness(self, url: str) -> int:
        return 255

    async def set_brightness(self, url: str, brightness: int) -> None:
        pass

    async def set_color(self, url: str, color, **kwargs) -> None:
        pass
