"""Support for VersaSense actuator peripheral."""

import logging
from typing import Any, override

from homeassistant.components.switch import SwitchEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

from . import DOMAIN
from .const import (
    KEY_CONSUMER,
    KEY_IDENTIFIER,
    KEY_MEASUREMENT,
    KEY_PARENT_MAC,
    KEY_PARENT_NAME,
    KEY_UNIT,
    PERIPHERAL_STATE_OFF,
    PERIPHERAL_STATE_ON,
)

_LOGGER = logging.getLogger(__name__)


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

    consumer = hass.data[DOMAIN][KEY_CONSUMER]

    actuator_list = []

    for entity_info in discovery_info.values():
        peripheral = hass.data[DOMAIN][entity_info[KEY_PARENT_MAC]][
            entity_info[KEY_IDENTIFIER]
        ]
        parent_name = entity_info[KEY_PARENT_NAME]
        unit = entity_info[KEY_UNIT]
        measurement = entity_info[KEY_MEASUREMENT]

        actuator_list.append(
            VActuator(peripheral, parent_name, unit, measurement, consumer)
        )

    async_add_entities(actuator_list)


class VActuator(SwitchEntity):
    """Representation of an Actuator."""

    def __init__(self, peripheral, parent_name, unit, measurement, consumer):
        """Initialize the sensor."""
        self._attr_is_on = False
        self._attr_name = f"{parent_name} {measurement}"
        self._attr_unique_id = (
            f"{peripheral.parentMac}/{peripheral.identifier}/{measurement}"
        )

        self._parent_mac = peripheral.parentMac
        self._identifier = peripheral.identifier
        self._unit = unit
        self._measurement = measurement
        self.consumer = consumer

    @override
    async def async_turn_off(self, **kwargs: Any) -> None:
        """Turn off the actuator."""
        await self.update_state(0)

    @override
    async def async_turn_on(self, **kwargs: Any) -> None:
        """Turn on the actuator."""
        await self.update_state(1)

    async def update_state(self, state):
        """Update the state of the actuator."""
        payload = {"id": "state-num", "value": state}

        await self.consumer.actuatePeripheral(
            None, self._identifier, self._parent_mac, payload
        )

    async def async_update(self) -> None:
        """Fetch state data from the actuator."""
        samples = await self.consumer.fetchPeripheralSample(
            None, self._identifier, self._parent_mac
        )

        if samples is not None:
            for sample in samples:
                if sample.measurement == self._measurement:
                    self._attr_available = True
                    if sample.value == PERIPHERAL_STATE_OFF:
                        self._attr_is_on = False
                    elif sample.value == PERIPHERAL_STATE_ON:
                        self._attr_is_on = True
                    break
        else:
            _LOGGER.error("Sample unavailable")
            self._attr_available = False
            self._attr_is_on = None
