"""Spook - Your homie."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any

from homeassistant.components import (
    automation,
    input_boolean,
    input_button,
    input_datetime,
    input_number,
    input_select,
    input_text,
    persistent_notification,
    person,
    script,
    sun,
    zone,
)
from homeassistant.components.sensor import (
    SensorEntity,
    SensorEntityDescription,
    SensorStateClass,
)
from homeassistant.const import (
    EVENT_COMPONENT_LOADED,
    EVENT_HOMEASSISTANT_STARTED,
    EntityCategory,
    Platform,
)
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers import (
    area_registry as ar,
    device_registry as dr,
    entity_registry as er,
)
from homeassistant.helpers.event import async_call_later

from ...entity import SpookEntityDescription
from ...listeners import async_listen_once_tracked
from .entity import HomeAssistantSpookEntity

if TYPE_CHECKING:
    from collections.abc import Callable
    from datetime import datetime  # Moved datetime here

    from homeassistant.config_entries import ConfigEntry
    from homeassistant.helpers.entity_platform import AddEntitiesCallback
    from homeassistant.util.event_type import EventType


@dataclass(frozen=True, kw_only=True)
class HomeAssistantSpookSensorEntityDescription(
    SpookEntityDescription,
    SensorEntityDescription,
):
    """Class describing Spook Home Assistant sensor entities."""

    value_fn: Callable[[HomeAssistant], int | None]
    update_events: set[EventType[Any] | str] = field(default_factory=set)


@callback
def _count_active_domain_entities(hass: HomeAssistant, domain: str) -> int:
    """Count domain entities that are not restored placeholders."""
    return sum(
        (state := hass.states.get(entity_id)) is not None
        and not state.attributes.get("restored", False)
        for entity_id in hass.states.async_entity_ids(domain)
    )


SENSORS: tuple[HomeAssistantSpookSensorEntityDescription, ...] = (
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.AIR_QUALITY,
        translation_key="homeassistant_air_quality",
        entity_id="sensor.air_quality",
        icon="mdi:air-filter",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.AIR_QUALITY)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.ALARM_CONTROL_PANEL,
        translation_key="homeassistant_alarm_control_panel",
        entity_id="sensor.alarm_control_panels",
        icon="mdi:alarm-panel",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(
            hass.states.async_entity_ids(Platform.ALARM_CONTROL_PANEL),
        ),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="area",
        translation_key="homeassistant_area",
        entity_id="sensor.areas",
        icon="mdi:texture-box",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, ar.EVENT_AREA_REGISTRY_UPDATED},
        value_fn=lambda hass: len(list(ar.async_get(hass).async_list_areas())),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=automation.DOMAIN,
        translation_key="homeassistant_automation",
        entity_id="sensor.automations",
        icon="mdi:robot",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={automation.EVENT_AUTOMATION_RELOADED},
        value_fn=lambda hass: _count_active_domain_entities(hass, automation.DOMAIN),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.BINARY_SENSOR,
        translation_key="homeassistant_binary_sensor",
        entity_id="sensor.binary_sensors",
        icon="mdi:numeric-10",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.BINARY_SENSOR)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.BUTTON,
        translation_key="homeassistant_button",
        entity_id="sensor.buttons",
        icon="mdi:gesture-tap",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.BUTTON)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.CALENDAR,
        translation_key="homeassistant_calendar",
        entity_id="sensor.calendars",
        icon="mdi:calendar",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CALENDAR)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.CAMERA,
        translation_key="homeassistant_camera",
        entity_id="sensor.cameras",
        icon="mdi:cctv",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CAMERA)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.CLIMATE,
        translation_key="homeassistant_climate",
        entity_id="sensor.climate",
        icon="mdi:thermostat",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CLIMATE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.COVER,
        translation_key="homeassistant_cover",
        entity_id="sensor.covers",
        icon="mdi:blinds",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.COVER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.DATE,
        translation_key="homeassistant_date",
        entity_id="sensor.dates",
        icon="mdi:calendar-month-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.DATE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.DATETIME,
        translation_key="homeassistant_datetime",
        entity_id="sensor.datetimes",
        icon="mdi:calendar-clock",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.DATETIME)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="device",
        translation_key="homeassistant_device",
        entity_id="sensor.devices",
        icon="mdi:cellphone",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, dr.EVENT_DEVICE_REGISTRY_UPDATED},
        value_fn=lambda hass: len(dr.async_get(hass).devices),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.DEVICE_TRACKER,
        translation_key="homeassistant_device_tracker",
        entity_id="sensor.device_trackers",
        icon="mdi:cellphone-marker",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(
            hass.states.async_entity_ids(Platform.DEVICE_TRACKER),
        ),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="entities",
        translation_key="homeassistant_entities",
        entity_id="sensor.entities",
        icon="mdi:counter",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids()),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.FAN,
        translation_key="homeassistant_fan",
        entity_id="sensor.fans",
        icon="mdi:fan",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.FAN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.HUMIDIFIER,
        translation_key="homeassistant_humidifier",
        entity_id="sensor.humidifiers",
        icon="mdi:air-humidifier",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.HUMIDIFIER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="integration",
        translation_key="homeassistant_integration",
        entity_id="sensor.integrations",
        icon="mdi:package-variant-closed",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED},
        value_fn=lambda hass: len(hass.data["entity_platform"]),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="custom_component",
        translation_key="homeassistant_custom_component",
        entity_id="sensor.custom_integrations",
        icon="mdi:package-variant-closed",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED},
        value_fn=lambda hass: len(hass.data["custom_components"]),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_boolean.DOMAIN,
        translation_key="homeassistant_input_boolean",
        entity_id="sensor.input_booleans",
        icon="mdi:toggle-switch-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_boolean.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_button.DOMAIN,
        translation_key="homeassistant_input_button",
        entity_id="sensor.input_buttons",
        icon="mdi:gesture-tap-button",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_button.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_datetime.DOMAIN,
        translation_key="homeassistant_input_datetime",
        entity_id="sensor.input_datetimes",
        icon="mdi:clock",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_datetime.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_number.DOMAIN,
        translation_key="homeassistant_input_number",
        entity_id="sensor.input_numbers",
        icon="mdi:ray-vertex",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_number.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_select.DOMAIN,
        translation_key="homeassistant_input_select",
        entity_id="sensor.input_selects",
        icon="mdi:form-dropdown",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_select.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=input_text.DOMAIN,
        translation_key="homeassistant_input_text",
        entity_id="sensor.input_texts",
        icon="mdi:form-textbox",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(input_text.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.IMAGE,
        translation_key="homeassistant_image",
        entity_id="sensor.images",
        icon="mdi:image",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.IMAGE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.LIGHT,
        translation_key="homeassistant_light",
        entity_id="sensor.lights",
        icon="mdi:lightbulb",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.LIGHT)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.LOCK,
        translation_key="homeassistant_lock",
        entity_id="sensor.locks",
        icon="mdi:lock",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.LOCK)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.MEDIA_PLAYER,
        translation_key="homeassistant_media_player",
        entity_id="sensor.media_players",
        icon="mdi:record-player",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.MEDIA_PLAYER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.NUMBER,
        translation_key="homeassistant_number",
        entity_id="sensor.numbers",
        icon="mdi:ray-vertex",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.NUMBER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key="persistent_notification",
        translation_key="homeassistant_persistent_notification",
        entity_id="sensor.persistent_notifications",
        icon="mdi:bell-ring-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={
            "persistent_notifications_updated",
        },
        value_fn=lambda hass: len(
            # pylint: disable-next=protected-access
            persistent_notification._async_get_or_create_notifications(  # noqa: SLF001
                hass,
            ),
        ),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=person.DOMAIN,
        translation_key="homeassistant_person",
        entity_id="sensor.persons",
        icon="mdi:account-group",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(person.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.REMOTE,
        translation_key="homeassistant_remote",
        entity_id="sensor.remotes",
        icon="mdi:remote",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.REMOTE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.SCENE,
        translation_key="homeassistant_scene",
        entity_id="sensor.scenes",
        icon="mdi:palette",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SCENE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=script.DOMAIN,
        translation_key="homeassistant_script",
        entity_id="sensor.scripts",
        icon="mdi:script-text",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: _count_active_domain_entities(hass, script.DOMAIN),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.SELECT,
        translation_key="homeassistant_select",
        entity_id="sensor.selects",
        icon="mdi:format-list-bulleted",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SELECT)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.SENSOR,
        translation_key="homeassistant_sensor",
        entity_id="sensor.sensors",
        icon="mdi:eye",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SENSOR)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.SIREN,
        translation_key="homeassistant_siren",
        entity_id="sensor.sirens",
        icon="mdi:bullhorn",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SIREN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=sun.DOMAIN,
        translation_key="homeassistant_sun",
        entity_id="sensor.suns",
        icon="mdi:emoticon-cool",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(sun.DOMAIN)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.STT,
        translation_key="homeassistant_stt",
        entity_id="sensor.stt",
        icon="mdi:microphone-message",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.STT)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.SWITCH,
        translation_key="homeassistant_switch",
        entity_id="sensor.switches",
        icon="mdi:toggle-switch",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SWITCH)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.TEXT,
        translation_key="homeassistant_text",
        entity_id="sensor.texts",
        icon="mdi:form-textbox",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TEXT)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.TIME,
        translation_key="homeassistant_time",
        entity_id="sensor.times",
        icon="mdi:clock-time-eight-outline",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TIME)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.TODO,
        translation_key="homeassistant_todo",
        entity_id="sensor.todos",
        icon="mdi:clipboard-list",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TODO)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.TTS,
        translation_key="homeassistant_tts",
        entity_id="sensor.tts",
        icon="mdi:speaker-message",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TTS)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.VACUUM,
        translation_key="homeassistant_vacuum",
        entity_id="sensor.vacuums",
        icon="mdi:vacuum",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.VACUUM)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.UPDATE,
        translation_key="homeassistant_update",
        entity_id="sensor.update",
        icon="mdi:cellphone-arrow-down",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.UPDATE)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.WATER_HEATER,
        translation_key="homeassistant_water_heater",
        entity_id="sensor.water_heaters",
        icon="mdi:water-boiler",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.WATER_HEATER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=Platform.WEATHER,
        translation_key="homeassistant_weather",
        entity_id="sensor.weather",
        icon="mdi:weather-cloudy",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.WEATHER)),
    ),
    HomeAssistantSpookSensorEntityDescription(
        key=zone.DOMAIN,
        translation_key="homeassistant_zone",
        entity_id="sensor.zones",
        icon="mdi:selection-marker",
        entity_category=EntityCategory.DIAGNOSTIC,
        state_class=SensorStateClass.TOTAL,
        update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
        value_fn=lambda hass: len(hass.states.async_entity_ids(zone.DOMAIN)),
    ),
)


async def async_setup_entry(
    _hass: HomeAssistant,
    _entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Spook sensor."""
    async_add_entities(
        HomeAssistantSpookSensorEntity(description) for description in SENSORS
    )


class HomeAssistantSpookSensorEntity(HomeAssistantSpookEntity, SensorEntity):
    """Spook sensor providig Home Asistant information."""

    entity_description: HomeAssistantSpookSensorEntityDescription
    _unsub_debouncer: Callable[[], None] | None = None

    async def async_added_to_hass(self) -> None:
        """Register for sensor updates."""

        @callback
        def _debounced_update(
            _now: datetime | None = None,
        ) -> None:
            """Update state after debounce."""
            self._unsub_debouncer = None
            self.async_schedule_update_ha_state()

        @callback
        def _update_state(_: Event) -> None:
            """Update state."""
            if self._unsub_debouncer:
                self._unsub_debouncer()
            self._unsub_debouncer = async_call_later(self.hass, 5, _debounced_update)

        for event in self.entity_description.update_events:
            self.async_on_remove(self.hass.bus.async_listen(event, _update_state))

        self.async_on_remove(
            async_listen_once_tracked(
                self.hass, EVENT_HOMEASSISTANT_STARTED, _update_state
            ),
        )

    async def async_will_remove_from_hass(self) -> None:
        """Clean up debounce timer."""
        if self._unsub_debouncer:
            self._unsub_debouncer()
            self._unsub_debouncer = None
        await super().async_will_remove_from_hass()

    @property
    def native_value(self) -> int | None:
        """Return the sensor value."""
        return self.entity_description.value_fn(self.hass)
