"""Support for events."""

from typing import Final, override

from aioamazondevices.const.devices import SPEAKER_GROUP_FAMILY

from homeassistant.components.event import (
    DOMAIN as EVENT_DOMAIN,
    EventEntity,
    EventEntityDescription,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .const import LOGGER
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
from .entity import AmazonEntity
from .utils import async_remove_entity_from_virtual_group

# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0

EVENTS: Final = {
    EventEntityDescription(
        key="voice_event",
        translation_key="voice_event",
    ),
}

EVENT_TYPE = "triggered"


async def async_setup_entry(
    hass: HomeAssistant,
    entry: AmazonConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up Alexa Devices events based on a config entry."""
    coordinator = entry.runtime_data

    # Remove voice event from virtual groups
    await async_remove_entity_from_virtual_group(
        hass, coordinator, EVENT_DOMAIN, "voice_event"
    )

    known_devices: set[str] = set()

    def _check_device() -> None:
        current_devices = set(coordinator.data)
        new_devices = current_devices - known_devices
        if new_devices:
            known_devices.update(new_devices)
            async_add_entities(
                AlexaVoiceEvent(coordinator, serial_num, event_desc)
                for event_desc in EVENTS
                for serial_num in new_devices
                if coordinator.data[serial_num].device_family != SPEAKER_GROUP_FAMILY
            )

    _check_device()
    entry.async_on_unload(coordinator.async_add_listener(_check_device))


class AlexaVoiceEvent(AmazonEntity, EventEntity):
    """Representation of an Alexa voice event."""

    _attr_event_types = [EVENT_TYPE]
    coordinator: AmazonDevicesCoordinator
    _last_seen_timestamp: int = 0  #  January 1, 1970 at 12:00:00 AM

    @callback
    @override
    def _handle_coordinator_update(self) -> None:
        """Handle updated data from the coordinator."""

        if not (
            vocal_record := self.coordinator.vocal_records.get(
                self.device.serial_number
            )
        ):
            LOGGER.debug(
                "No vocal record found for device %s [%s]",
                self.device.account_name,
                self.device.serial_number,
            )
            return

        if vocal_record.timestamp <= self._last_seen_timestamp:
            # Discard old events that have already been processed
            return

        self._last_seen_timestamp = vocal_record.timestamp
        self._trigger_event(
            EVENT_TYPE,
            {
                "intent": vocal_record.intent,
                "voice_command": vocal_record.title,
                "voice_reply": vocal_record.sub_title,
            },
        )
        self.async_write_ha_state()
