"""Tests for HomematicIP Cloud switch."""

from homeassistant.components.homematicip_cloud.entity import (
    ATTR_GROUP_MEMBER_UNREACHABLE,
)
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant

from .helper import HomeFactory, async_manipulate_test_data, get_and_check_entity_basics


async def test_hmip_switch(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipSwitch."""
    entity_id = "switch.schrank"
    entity_name = "Schrank"
    device_model = "HMIP-PS"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=[entity_name]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_ON
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON


async def test_hmip_switch_input(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipSwitch."""
    entity_id = "switch.wohnzimmer_beleuchtung"
    entity_name = "Wohnzimmer Beleuchtung"
    device_model = "HmIP-FSI16"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=[entity_name]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_ON
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON


async def test_hmip_switch_measuring(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipSwitchMeasuring."""
    entity_id = "switch.pc"
    entity_name = "Pc"
    device_model = "HMIP-PSM"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=[entity_name]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_ON
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    await async_manipulate_test_data(hass, hmip_device, "currentPowerConsumption", 50)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON


async def test_hmip_group_switch(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipGroupSwitch."""
    entity_id = "switch.strom_group"
    entity_name = "Strom Group"
    device_model = None
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(test_groups=["Strom"])

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_ON
    service_call_counter = len(hmip_device.mock_calls)

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.mock_calls) == service_call_counter + 1
    assert hmip_device.mock_calls[-1][0] == "turn_off_async"
    assert hmip_device.mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.mock_calls) == service_call_counter + 3
    assert hmip_device.mock_calls[-1][0] == "turn_on_async"
    assert hmip_device.mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON

    assert not ha_state.attributes.get(ATTR_GROUP_MEMBER_UNREACHABLE)
    await async_manipulate_test_data(hass, hmip_device, "unreach", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.attributes[ATTR_GROUP_MEMBER_UNREACHABLE]


async def test_hmip_multi_switch(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipMultiSwitch."""
    entity_id = "switch.jalousien_1_kizi_2_schlazi_channel1"
    entity_name = "Jalousien - 1 KiZi, 2 SchlaZi Channel1"
    device_model = "HmIP-PCBS2"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=[
            "Jalousien - 1 KiZi, 2 SchlaZi",
            "Multi IO Box",
            "Heizungsaktor",
            "ioBroker",
            "Schaltaktor Verteiler",
        ]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_OFF
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    ha_state, hmip_device = get_and_check_entity_basics(
        hass,
        mock_hap,
        "switch.schaltaktor_verteiler_channel3",
        "Schaltaktor Verteiler Channel3",
        "HmIP-DRSI4",
    )

    assert ha_state.state == STATE_OFF


async def test_hmip_wired_multi_switch(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipMultiSwitch."""
    entity_id = "switch.wired_schaltaktor_8_fach_fernseher_wohnzimmer"
    entity_name = "Wired Schaltaktor – 8-fach Fernseher (Wohnzimmer)"
    device_model = "HmIPW-DRS8"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=[
            "Wired Schaltaktor – 8-fach",
        ]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_ON
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_off", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", False)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_OFF

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    assert hmip_device.functionalChannels[1].mock_calls[-1][1] == ()
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON


async def test_hmip_status_board_switch(
    hass: HomeAssistant, default_mock_hap_factory: HomeFactory
) -> None:
    """Test HomematicipMultiSwitch with StatusBoard8."""
    entity_id = "switch.status_board_led_1"
    entity_name = "Status Board LED 1"
    device_model = "ELV-SH-SB8"
    mock_hap = await default_mock_hap_factory.async_get_mock_hap(
        test_devices=["Status Board"]
    )

    ha_state, hmip_device = get_and_check_entity_basics(
        hass, mock_hap, entity_id, entity_name, device_model
    )

    assert ha_state.state == STATE_OFF
    service_call_counter = len(hmip_device.functionalChannels[1].mock_calls)

    await hass.services.async_call(
        "switch", "turn_on", {"entity_id": entity_id}, blocking=True
    )
    assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1
    assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on"
    await async_manipulate_test_data(hass, hmip_device, "on", True)
    ha_state = hass.states.get(entity_id)
    assert ha_state.state == STATE_ON

    # Verify second channel exists and has correct initial state (on=true in fixture)
    ha_state2 = hass.states.get("switch.status_board_led_2")
    assert ha_state2 is not None
    assert ha_state2.state == STATE_ON
