"""Test homekit_controller stateless triggers."""

from collections.abc import Callable

from aiohomekit.model import Accessory
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes

from homeassistant.components.event import EventDeviceClass
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er

from .common import setup_test_component


def create_remote(accessory: Accessory) -> None:
    """Define characteristics for a button (that is inn a group)."""
    service_label = accessory.add_service(ServicesTypes.SERVICE_LABEL)

    char = service_label.add_char(CharacteristicsTypes.SERVICE_LABEL_NAMESPACE)
    char.value = 1

    for i in range(4):
        button = accessory.add_service(ServicesTypes.STATELESS_PROGRAMMABLE_SWITCH)
        button.linked.append(service_label)

        char = button.add_char(CharacteristicsTypes.INPUT_EVENT)
        char.value = 0
        char.perms = ["pw", "pr", "ev"]

        char = button.add_char(CharacteristicsTypes.NAME)
        char.value = f"Button {i + 1}"

        char = button.add_char(CharacteristicsTypes.SERVICE_LABEL_INDEX)
        char.value = i

    battery = accessory.add_service(ServicesTypes.BATTERY_SERVICE)
    battery.add_char(CharacteristicsTypes.BATTERY_LEVEL)


def create_button(accessory: Accessory) -> None:
    """Define a button (that is not in a group)."""
    button = accessory.add_service(ServicesTypes.STATELESS_PROGRAMMABLE_SWITCH)

    char = button.add_char(CharacteristicsTypes.INPUT_EVENT)
    char.value = 0
    char.perms = ["pw", "pr", "ev"]

    char = button.add_char(CharacteristicsTypes.NAME)
    char.value = "Button 1"

    battery = accessory.add_service(ServicesTypes.BATTERY_SERVICE)
    battery.add_char(CharacteristicsTypes.BATTERY_LEVEL)


def create_doorbell(accessory: Accessory) -> None:
    """Define a button (that is not in a group)."""
    button = accessory.add_service(ServicesTypes.DOORBELL)

    char = button.add_char(CharacteristicsTypes.INPUT_EVENT)
    char.value = 0
    char.perms = ["pw", "pr", "ev"]

    char = button.add_char(CharacteristicsTypes.NAME)
    char.value = "Doorbell"

    battery = accessory.add_service(ServicesTypes.BATTERY_SERVICE)
    battery.add_char(CharacteristicsTypes.BATTERY_LEVEL)


async def test_remote(
    hass: HomeAssistant,
    entity_registry: er.EntityRegistry,
    get_next_aid: Callable[[], int],
) -> None:
    """Test that remote is supported."""
    helper = await setup_test_component(hass, get_next_aid(), create_remote)

    entities = [
        ("event.testdevice_button_1", "Button 1"),
        ("event.testdevice_button_2", "Button 2"),
        ("event.testdevice_button_3", "Button 3"),
        ("event.testdevice_button_4", "Button 4"),
    ]

    for entity_id, service in entities:
        button = entity_registry.async_get(entity_id)

        assert button.original_device_class == EventDeviceClass.BUTTON
        assert button.capabilities["event_types"] == [
            "single_press",
            "double_press",
            "long_press",
        ]

        helper.pairing.testing.update_named_service(
            service, {CharacteristicsTypes.INPUT_EVENT: 0}
        )
        await hass.async_block_till_done()
        state = hass.states.get(entity_id)
        assert state.attributes["event_type"] == "single_press"

        helper.pairing.testing.update_named_service(
            service, {CharacteristicsTypes.INPUT_EVENT: 1}
        )
        await hass.async_block_till_done()
        state = hass.states.get(entity_id)
        assert state.attributes["event_type"] == "double_press"

        helper.pairing.testing.update_named_service(
            service, {CharacteristicsTypes.INPUT_EVENT: 2}
        )
        await hass.async_block_till_done()
        state = hass.states.get(entity_id)
        assert state.attributes["event_type"] == "long_press"


async def test_button(
    hass: HomeAssistant,
    entity_registry: er.EntityRegistry,
    get_next_aid: Callable[[], int],
) -> None:
    """Test that a button is correctly enumerated."""
    helper = await setup_test_component(hass, get_next_aid(), create_button)
    entity_id = "event.testdevice_button_1"

    button = entity_registry.async_get(entity_id)

    assert button.original_device_class == EventDeviceClass.BUTTON
    assert button.capabilities["event_types"] == [
        "single_press",
        "double_press",
        "long_press",
    ]

    helper.pairing.testing.update_named_service(
        "Button 1", {CharacteristicsTypes.INPUT_EVENT: 0}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "single_press"

    helper.pairing.testing.update_named_service(
        "Button 1", {CharacteristicsTypes.INPUT_EVENT: 1}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "double_press"

    helper.pairing.testing.update_named_service(
        "Button 1", {CharacteristicsTypes.INPUT_EVENT: 2}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "long_press"


async def test_doorbell(
    hass: HomeAssistant,
    entity_registry: er.EntityRegistry,
    get_next_aid: Callable[[], int],
) -> None:
    """Test that doorbell service is handled."""
    helper = await setup_test_component(hass, get_next_aid(), create_doorbell)
    entity_id = "event.testdevice_doorbell"

    doorbell = entity_registry.async_get(entity_id)

    assert doorbell.original_device_class == EventDeviceClass.DOORBELL
    assert doorbell.capabilities["event_types"] == [
        "single_press",
        "double_press",
        "long_press",
    ]

    helper.pairing.testing.update_named_service(
        "Doorbell", {CharacteristicsTypes.INPUT_EVENT: 0}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "single_press"

    helper.pairing.testing.update_named_service(
        "Doorbell", {CharacteristicsTypes.INPUT_EVENT: 1}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "double_press"

    helper.pairing.testing.update_named_service(
        "Doorbell", {CharacteristicsTypes.INPUT_EVENT: 2}
    )
    await hass.async_block_till_done()
    state = hass.states.get(entity_id)
    assert state.attributes["event_type"] == "long_press"