"""SteelSeries GameSense device provider — control SteelSeries RGB peripherals."""

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.gamesense_client import (
    GameSenseClient,
    GAMESENSE_ZONES,
    _get_gamesense_address,
)
from ledgrab.utils import get_logger

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

logger = get_logger(__name__)


class GameSenseDeviceProvider(LEDDeviceProvider):
    """Provider for SteelSeries GameSense RGB peripherals.

    URL format: gamesense://address or gamesense://auto (auto-discover from coreProps.json)
    Requires SteelSeries GG / SteelSeries Engine 3.
    """

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

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

    def create_client(self, config: "GameSenseConfig", *, deps: ProviderDeps) -> LEDClient:
        return GameSenseClient(
            url=config.device_url,
            led_count=config.led_count,
            gamesense_device_type=config.gamesense_device_type,
        )

    async def check_health(self, url: str, http_client, prev_health=None) -> DeviceHealth:
        return await GameSenseClient.check_health(url, http_client, prev_health)

    async def validate_device(self, url: str) -> dict:
        """Validate GameSense is reachable."""
        address = url.replace("gamesense://", "").strip()
        if not address or address == "auto":
            address = _get_gamesense_address()

        if not address:
            raise ValueError("Cannot find SteelSeries Engine. " "Ensure SteelSeries GG is running.")

        import httpx

        try:
            async with httpx.AsyncClient(timeout=3.0) as client:
                resp = await client.get(f"http://{address}")
                if resp.status_code >= 500:
                    raise ValueError("SteelSeries Engine returned server error")
        except httpx.ConnectError:
            raise ValueError(
                "Cannot connect to SteelSeries Engine at " f"{address}. Ensure it is running."
            )

        return {}

    async def discover(self, timeout: float = 3.0) -> List[DiscoveredDevice]:
        """Discover SteelSeries Engine if running."""
        address = _get_gamesense_address()
        if not address:
            return []

        import httpx

        try:
            async with httpx.AsyncClient(timeout=timeout) as client:
                resp = await client.get(f"http://{address}")
                if resp.status_code >= 500:
                    return []
        except Exception:
            return []

        # Engine is running — offer device types
        results = []
        for dev_type in GAMESENSE_ZONES:
            results.append(
                DiscoveredDevice(
                    name=f"SteelSeries {dev_type.title()}",
                    url=f"gamesense://{address}",
                    device_type="gamesense",
                    ip=address.split(":")[0],
                    mac="",
                    led_count=None,
                    version=None,
                )
            )
        return results
