"""DMX device provider — Art-Net / sACN (E1.31) factory, validation, health."""

from datetime import datetime, timezone
from typing import List
from urllib.parse import urlparse

from wled_controller.core.devices.led_client import (
    DeviceHealth,
    DiscoveredDevice,
    LEDClient,
    LEDDeviceProvider,
)
from wled_controller.core.devices.dmx_client import DMXClient
from wled_controller.utils import get_logger

logger = get_logger(__name__)


def parse_dmx_url(url: str) -> dict:
    """Parse a DMX URL like 'artnet://192.168.1.50' or 'sacn://192.168.1.50'.

    Returns dict with 'host', 'port', 'protocol'.
    Also accepts plain IP addresses (defaults to artnet).
    """
    url = url.strip()
    if "://" not in url:
        url = f"artnet://{url}"

    parsed = urlparse(url)
    protocol = parsed.scheme.lower()
    if protocol not in ("artnet", "sacn"):
        protocol = "artnet"

    host = parsed.hostname or "127.0.0.1"
    port = parsed.port  # None = use protocol default

    return {"host": host, "port": port, "protocol": protocol}


class DMXDeviceProvider(LEDDeviceProvider):
    """Provider for Art-Net and sACN (E1.31) DMX devices."""

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

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

    def create_client(self, url: str, **kwargs) -> LEDClient:
        parsed = parse_dmx_url(url)
        return DMXClient(
            host=parsed["host"],
            port=parsed["port"],
            led_count=kwargs.get("led_count", 1),
            protocol=kwargs.get("dmx_protocol", parsed["protocol"]),
            start_universe=kwargs.get("dmx_start_universe", 0),
            start_channel=kwargs.get("dmx_start_channel", 1),
        )

    async def check_health(
        self, url: str, http_client, prev_health=None,
    ) -> DeviceHealth:
        # DMX is UDP fire-and-forget — no reliable health probe.
        # Report as always online (same pattern as WS/Mock providers).
        return DeviceHealth(
            online=True,
            latency_ms=0.0,
            last_checked=datetime.now(timezone.utc),
        )

    async def validate_device(self, url: str) -> dict:
        """Validate DMX device URL."""
        parsed = parse_dmx_url(url)
        if not parsed["host"]:
            raise ValueError("DMX device requires a valid IP address or hostname")
        return {}

    async def discover(self, timeout: float = 3.0) -> List[DiscoveredDevice]:
        # No auto-discovery for DMX devices
        return []
