"""Support for the Vallox ventilation unit fan."""
from __future__ import annotations

from collections.abc import Mapping
import logging
from typing import Any

from vallox_websocket_api import Vallox
from vallox_websocket_api.exceptions import ValloxApiException

from homeassistant.components.fan import (
    SUPPORT_PRESET_MODE,
    FanEntity,
    NotValidPresetModeError,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

from . import ValloxStateProxy
from .const import (
    DOMAIN,
    METRIC_KEY_MODE,
    METRIC_KEY_PROFILE_FAN_SPEED_AWAY,
    METRIC_KEY_PROFILE_FAN_SPEED_BOOST,
    METRIC_KEY_PROFILE_FAN_SPEED_HOME,
    MODE_OFF,
    MODE_ON,
    SIGNAL_VALLOX_STATE_UPDATE,
    STR_TO_VALLOX_PROFILE_SETTABLE,
    VALLOX_PROFILE_TO_STR_SETTABLE,
)

_LOGGER = logging.getLogger(__name__)

ATTR_PROFILE_FAN_SPEED_HOME = {
    "description": "fan_speed_home",
    "metric_key": METRIC_KEY_PROFILE_FAN_SPEED_HOME,
}
ATTR_PROFILE_FAN_SPEED_AWAY = {
    "description": "fan_speed_away",
    "metric_key": METRIC_KEY_PROFILE_FAN_SPEED_AWAY,
}
ATTR_PROFILE_FAN_SPEED_BOOST = {
    "description": "fan_speed_boost",
    "metric_key": METRIC_KEY_PROFILE_FAN_SPEED_BOOST,
}


async def async_setup_platform(
    hass: HomeAssistant,
    config: ConfigType,
    async_add_entities: AddEntitiesCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the fan device."""
    if discovery_info is None:
        return

    client = hass.data[DOMAIN]["client"]
    client.set_settable_address(METRIC_KEY_MODE, int)

    device = ValloxFan(
        hass.data[DOMAIN]["name"], client, hass.data[DOMAIN]["state_proxy"]
    )

    async_add_entities([device], update_before_add=False)


class ValloxFan(FanEntity):
    """Representation of the fan."""

    _attr_should_poll = False

    def __init__(
        self, name: str, client: Vallox, state_proxy: ValloxStateProxy
    ) -> None:
        """Initialize the fan."""
        self._client = client
        self._state_proxy = state_proxy
        self._is_on = False
        self._preset_mode: str | None = None
        self._fan_speed_home: int | None = None
        self._fan_speed_away: int | None = None
        self._fan_speed_boost: int | None = None

        self._attr_name = name
        self._attr_available = False

    @property
    def supported_features(self) -> int:
        """Flag supported features."""
        return SUPPORT_PRESET_MODE

    @property
    def preset_modes(self) -> list[str]:
        """Return a list of available preset modes."""
        # Use the Vallox profile names for the preset names.
        return list(STR_TO_VALLOX_PROFILE_SETTABLE.keys())

    @property