"""Support for rain sensors built into some Velux windows."""

from typing import override

from pyvlx import Window

from homeassistant.components.binary_sensor import (
    BinarySensorDeviceClass,
    BinarySensorEntity,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from . import VeluxConfigEntry
from .coordinator import VeluxLimitationCoordinator
from .entity import velux_device_info, velux_unique_id

PARALLEL_UPDATES = 1


async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: VeluxConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up rain sensor(s) for Velux platform."""
    pyvlx = config_entry.runtime_data.pyvlx
    limitation_coordinators = config_entry.runtime_data.limitation_coordinators

    async_add_entities(
        VeluxRainSensor(limitation_coordinators[node.node_id], config_entry.entry_id)
        for node in pyvlx.nodes
        if isinstance(node, Window) and node.rain_sensor
    )


class VeluxRainSensor(
    CoordinatorEntity[VeluxLimitationCoordinator], BinarySensorEntity
):
    """Representation of a Velux rain sensor."""

    _attr_entity_registry_enabled_default = False
    _attr_device_class = BinarySensorDeviceClass.MOISTURE
    _attr_translation_key = "rain_sensor"
    _attr_has_entity_name = True

    def __init__(
        self, coordinator: VeluxLimitationCoordinator, config_entry_id: str
    ) -> None:
        """Initialize VeluxRainSensor."""
        super().__init__(coordinator)
        node = coordinator.node
        unique_id = velux_unique_id(node, config_entry_id)
        self._attr_unique_id = f"{unique_id}_rain_sensor"
        self._attr_device_info = velux_device_info(
            self.coordinator.hass, node, config_entry_id
        )

    @override
    async def async_added_to_hass(self) -> None:
        """Called when the entity is added to Home Assistant."""
        await super().async_added_to_hass()
        # Get initial state as we didn't do it on coordinator initialization to avoid doing it for disabled entities
        if self.coordinator.data is None:
            await self.coordinator.async_request_refresh()

    @property
    @override
    def is_on(self) -> bool | None:
        """Return true if rain is detected."""
        # Velux windows with rain sensors report an opening
        # limitation when rain is detected. So far we've
        # seen 89, 91, 93 (most cases) or 100 (Velux GPU).
        # It probably makes sense to assume that any large
        # enough limitation (we use >=89) means rain is detected.
        # Documentation on this is non-existent AFAIK.
        if self.coordinator.data is None:
            return None
        return self.coordinator.data.limitation_min.position_percent >= 89
