import logging
from typing import Any

from homeassistant.components.light import (
    LightEntityDescription,
    LightEntity,
    ColorMode,
    ATTR_BRIGHTNESS,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import HomeAssistantType
from pyhon.appliance import HonAppliance
from pyhon.parameter.range import HonParameterRange

from .const import DOMAIN
from .hon import HonEntity

_LOGGER = logging.getLogger(__name__)


LIGHTS: dict[str, tuple[LightEntityDescription, ...]] = {
    "WC": (
        LightEntityDescription(
            key="settings.lightStatus",
            name="Light",
            translation_key="light",
        ),
    ),
    "HO": (
        LightEntityDescription(
            key="settings.lightStatus",
            name="Light status",
            translation_key="light",
        ),
    ),
    "AP": (
        LightEntityDescription(
            key="settings.lightStatus",
            name="Light status",
            translation_key="light",
        ),
    ),
}


async def async_setup_entry(
    hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
    entities = []
    for device in hass.data[DOMAIN][entry.unique_id].appliances:
        for description in LIGHTS.get(device.appliance_type, []):
            if (
                description.key not in device.available_settings
                or device.get(description.key.split(".")[-1]) is None
            ):
                continue
            entity = HonLightEntity(hass, entry, device, description)
            await entity.coordinator.async_config_entry_first_refresh()
            entities.append(entity)
    async_add_entities(entities)


class HonLightEntity(HonEntity, LightEntity):
    entity_description: LightEntityDescription

    def __init__(
        self,
        hass: HomeAssistantType,
        entry: ConfigEntry,
        device: HonAppliance,
        description: LightEntityDescription,
    ) -> None:
        light = device.settings.get(description.key)
        if not isinstance(light, HonParameterRange):
            raise ValueError()
        self._light_range = (light.min, light.max)
        self._attr_supported_color_modes: set[ColorMode] = set()
        if len(light.values) == 2:
            self._attr_supported_color_modes.add(ColorMode.ONOFF)
        else:
            self._attr_supported_color_modes.add(ColorMode.BRIGHTNESS)
        self._command, self._parameter = description.key.split(".")
        super().__init__(hass, entry, device, description)
        self._handle_coordinator_update(update=False)

    @property
    def is_on(self) -> bool:
        """Return true if light is on."""
        return bool(self._device.get(self.entity_description.key.split(".")[-1]) > 0)

    async def async_turn_on(self, **kwargs: Any) -> None:
        """Turn on or control the light."""
        light = self._device.settings.get(self.entity_description.key)
        if not isinstance(light, HonParameterRange):
            raise ValueError()
        if ColorMode.BRIGHTNESS in self._attr_supported_color_modes:
            percent = int(100 / 255 * kwargs.get(ATTR_BRIGHTNESS, 128))
            light.value = round(light.max / 100 * percent)
            if light.value == light.min:
                self._attr_is_on = False
            self._attr_brightness = self.brightness
        else:
            light.value = light.max
        await self._device.commands[self._command].send()
        self.async_write_ha_state()

    async def async_turn_off(self, **kwargs: Any) -> None:
        """Instruct the light to turn off."""
        light = self._device.settings.get(self.entity_description.key)
        if not isinstance(light, HonParameterRange):
            raise ValueError()
        light.value = light.min
        await self._device.commands[self._command].send()
        self.async_write_ha_state()

    @property
    def brightness(self) -> int | None:
        """Return the brightness of the light."""
        light = self._device.settings.get(self.entity_description.key)
        if not isinstance(light, HonParameterRange):
            raise ValueError()
        if light.value == light.min:
            return None
        return int(255 / light.max * float(light.value))

    @callback
    def _handle_coordinator_update(self, update: bool = True) -> None:
        self._attr_is_on = self.is_on
        self._attr_brightness = self.brightness
        if update:
            self.async_write_ha_state()

    @property
    def available(self) -> bool:
        if (entity := self._device.settings.get(self.entity_description.key)) is None:
            return False
        return super().available and len(entity.values) > 1
