"""Support for ZHA controls using the select platform."""

import functools
import logging
from typing import override

from homeassistant.components.select import SelectEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .entity import ZHAEntity
from .helpers import (
    SIGNAL_ADD_ENTITIES,
    async_add_entities as zha_async_add_entities,
    convert_zha_error_to_ha_error,
    get_zha_data,
)

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up the Zigbee Home Automation siren from config entry."""
    zha_data = get_zha_data(hass)
    entities_to_create = zha_data.platforms[Platform.SELECT]

    unsub = async_dispatcher_connect(
        hass,
        SIGNAL_ADD_ENTITIES,
        functools.partial(
            zha_async_add_entities,
            async_add_entities,
            ZHAEnumSelectEntity,
            entities_to_create,
        ),
    )
    config_entry.async_on_unload(unsub)


class ZHAEnumSelectEntity(ZHAEntity, SelectEntity):
    """Representation of a ZHA select entity."""

    @override
    def _update_capability_attrs(self) -> None:
        """Re-derive capability attributes from the cached state."""
        self._attr_options = self._zha_state.options

    @property
    @override
    def current_option(self) -> str | None:
        """Return the selected entity option to represent the entity state."""
        return self._zha_state.current_option

    @convert_zha_error_to_ha_error()
    @override
    async def async_select_option(self, option: str) -> None:
        """Change the selected option."""
        await self.entity_data.entity.async_select_option(option=option)
        self.async_write_ha_state()

    @callback
    @override
    def restore_external_state_attributes(self, state: State) -> None:
        """Restore entity state."""
        if state.state and state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE):
            self.entity_data.entity.restore_external_state_attributes(
                state=state.state,
            )
