"""MQTT device provider — factory, validation, health checks."""

from __future__ import annotations

from typing import TYPE_CHECKING, List

from ledgrab.core.devices.led_client import (
    DeviceHealth,
    DiscoveredDevice,
    LEDClient,
    LEDDeviceProvider,
    ProviderDeps,
)
from ledgrab.core.devices.mqtt_client import (
    MQTTLEDClient,
    parse_mqtt_url,
)
from ledgrab.utils import get_logger

if TYPE_CHECKING:
    from ledgrab.core.devices.device_config import MQTTConfig

logger = get_logger(__name__)


class MQTTDeviceProvider(LEDDeviceProvider):
    """Provider for MQTT-based LED devices."""

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

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

    def create_client(self, config: "MQTTConfig", *, deps: ProviderDeps) -> LEDClient:
        return MQTTLEDClient(
            config.device_url,
            led_count=config.led_count,
            mqtt_manager=deps.mqtt_manager,
            mqtt_source_id=config.mqtt_source_id,
        )

    async def check_health(
        self,
        url: str,
        http_client,
        prev_health=None,
    ) -> DeviceHealth:
        # The provider-level check doesn't know which source the device
        # references; the runtime check is best-effort. The healthier path
        # is to wire mqtt_manager into the health monitor — for now we just
        # return "unknown" so the dashboard doesn't show a stale "online".
        from datetime import datetime, timezone

        return DeviceHealth(
            online=False,
            error="MQTT health requires mqtt_source_id (per-device runtime check)",
            last_checked=datetime.now(timezone.utc),
        )

    async def validate_device(self, url: str) -> dict:
        """Validate MQTT device URL (topic path)."""
        topic = parse_mqtt_url(url)
        if not topic or topic == "/":
            raise ValueError("MQTT topic cannot be empty")
        # Can't auto-detect LED count — require manual entry
        return {}

    async def discover(self, timeout: float = 3.0) -> List[DiscoveredDevice]:
        # MQTT devices are not auto-discoverable
        return []
