"""Select platform for LED Screen Controller (CSS source & brightness source)."""
from __future__ import annotations

import logging
from typing import Any

from homeassistant.components.select import SelectEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN, DATA_COORDINATOR, TARGET_TYPE_KEY_COLORS
from .coordinator import WLEDScreenControllerCoordinator

_LOGGER = logging.getLogger(__name__)

NONE_OPTION = "— None —"


async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up LED Screen Controller select entities."""
    data = hass.data[DOMAIN][entry.entry_id]
    coordinator: WLEDScreenControllerCoordinator = data[DATA_COORDINATOR]

    entities: list[SelectEntity] = []
    if coordinator.data and "targets" in coordinator.data:
        for target_id, target_data in coordinator.data["targets"].items():
            info = target_data["info"]

            # Only LED targets
            if info.get("target_type") == TARGET_TYPE_KEY_COLORS:
                continue

            entities.append(
                CSSSourceSelect(coordinator, target_id, entry.entry_id)
            )
            entities.append(
                BrightnessSourceSelect(coordinator, target_id, entry.entry_id)
            )

    async_add_entities(entities)


class CSSSourceSelect(CoordinatorEntity, SelectEntity):
    """Select entity for choosing a color strip source for an LED target."""

    _attr_has_entity_name = True
    _attr_icon = "mdi:palette"

    def __init__(
        self,
        coordinator: WLEDScreenControllerCoordinator,
        target_id: str,
        entry_id: str,
    ) -> None:
        super().__init__(coordinator)
        self._target_id = target_id
        self._entry_id = entry_id
        self._attr_unique_id = f"{target_id}_css_source"
        self._attr_translation_key = "color_strip_source"

    @property
    def device_info(self) -> dict[str, Any]:
        return {"identifiers": {(DOMAIN, self._target_id)}}

    @property
    def options(self) -> list[str]:
        if not self.coordinator.data:
            return []
        sources = self.coordinator.data.get("css_sources") or []
        return [s["name"] for s in sources]

    @property
    def current_option(self) -> str | None:
        if not self.coordinator.data:
            return None
        target_data = self.coordinator.data.get("targets", {}).get(self._target_id)
        if not target_data:
            return None
        current_id = target_data["info"].get("color_strip_source_id", "")
        sources = self.coordinator.data.get("css_sources") or []
        for s in sources:
            if s["id"] == current_id:
                return s["name"]
        return None

    @property
    def available(self) -> bool:
        if not self.coordinator.data:
            return False
        return self._target_id in self.coordinator.data.get("targets", {})

    async def async_select_option(self, option: str) -> None:
        source_id = self._name_to_id_map().get(option)
        if source_id is None:
            _LOGGER.error("CSS source not found: %s", option)
            return
        await self.coordinator.update_target(
            self._target_id, color_strip_source_id=source_id
        )

    def _name_to_id_map(self) -> dict[str, str]:
        sources = (self.coordinator.data or {}).get("css_sources") or []
        return {s["name"]: s["id"] for s in sources}


class BrightnessSourceSelect(CoordinatorEntity, SelectEntity):
    """Select entity for choosing a brightness value source for an LED target."""

    _attr_has_entity_name = True
    _attr_icon = "mdi:brightness-auto"

    def __init__(
        self,
        coordinator: WLEDScreenControllerCoordinator,
        target_id: str,
        entry_id: str,
    ) -> None:
        super().__init__(coordinator)
        self._target_id = target_id
        self._entry_id = entry_id
        self._attr_unique_id = f"{target_id}_brightness_source"
        self._attr_translation_key = "brightness_source"

    @property
    def device_info(self) -> dict[str, Any]:
        return {"identifiers": {(DOMAIN, self._target_id)}}

    @property
    def options(self) -> list[str]:
        if not self.coordinator.data:
            return [NONE_OPTION]
        sources = self.coordinator.data.get("value_sources") or []
        return [NONE_OPTION] + [s["name"] for s in sources]

    @property
    def current_option(self) -> str | None:
        if not self.coordinator.data:
            return None
        target_data = self.coordinator.data.get("targets", {}).get(self._target_id)
        if not target_data:
            return None
        current_id = target_data["info"].get("brightness_value_source_id", "")
        if not current_id:
            return NONE_OPTION
        sources = self.coordinator.data.get("value_sources") or []
        for s in sources:
            if s["id"] == current_id:
                return s["name"]
        return NONE_OPTION

    @property
    def available(self) -> bool:
        if not self.coordinator.data:
            return False
        return self._target_id in self.coordinator.data.get("targets", {})

    async def async_select_option(self, option: str) -> None:
        if option == NONE_OPTION:
            source_id = ""
        else:
            name_map = {
                s["name"]: s["id"]
                for s in (self.coordinator.data or {}).get("value_sources") or []
            }
            source_id = name_map.get(option)
            if source_id is None:
                _LOGGER.error("Value source not found: %s", option)
                return
        await self.coordinator.update_target(
            self._target_id, brightness_value_source_id=source_id
        )
