"""Tests for Ecovacs sensors."""

from deebot_client.command import Command
from deebot_client.commands import StationAction
from deebot_client.commands.json import (
    ResetLifeSpan,
    SetRelocationState,
    station_action,
)
from deebot_client.events import LifeSpan
import pytest
from syrupy.assertion import SnapshotAssertion

from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.components.ecovacs.const import DOMAIN
from homeassistant.components.ecovacs.controller import EcovacsController
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er

pytestmark = [
    pytest.mark.usefixtures("init_integration"),
    pytest.mark.freeze_time("2024-01-01 00:00:00"),
]


@pytest.fixture
def platforms() -> Platform | list[Platform]:
    """Platforms, which should be loaded during the test."""
    return Platform.BUTTON


@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize(
    ("device_fixture", "entities"),
    [
        (
            "yna5x1",
            [
                ("button.ozmo_950_relocate", SetRelocationState()),
                (
                    "button.ozmo_950_reset_main_brush_lifespan",
                    ResetLifeSpan(LifeSpan.BRUSH),
                ),
                (
                    "button.ozmo_950_reset_filter_lifespan",
                    ResetLifeSpan(LifeSpan.FILTER),
                ),
                (
                    "button.ozmo_950_reset_side_brush_lifespan",
                    ResetLifeSpan(LifeSpan.SIDE_BRUSH),
                ),
            ],
        ),
        (
            "5xu9h3",
            [
                (
                    "button.goat_g1_reset_blade_lifespan",
                    ResetLifeSpan(LifeSpan.BLADE),
                ),
                (
                    "button.goat_g1_reset_lens_brush_lifespan",
                    ResetLifeSpan(LifeSpan.LENS_BRUSH),
                ),
            ],
        ),
        (
            "qhe2o2",
            [
                ("button.dusty_relocate", SetRelocationState()),
                (
                    "button.dusty_reset_main_brush_lifespan",
                    ResetLifeSpan(LifeSpan.BRUSH),
                ),
                (
                    "button.dusty_reset_filter_lifespan",
                    ResetLifeSpan(LifeSpan.FILTER),
                ),
                (
                    "button.dusty_reset_round_mop_lifespan",
                    ResetLifeSpan(LifeSpan.ROUND_MOP),
                ),
                (
                    "button.dusty_reset_side_brush_lifespan",
                    ResetLifeSpan(LifeSpan.SIDE_BRUSH),
                ),
                (
                    "button.dusty_reset_unit_care_lifespan",
                    ResetLifeSpan(LifeSpan.UNIT_CARE),
                ),
                (
                    "button.dusty_empty_dustbin",
                    station_action.StationAction(StationAction.EMPTY_DUSTBIN),
                ),
            ],
        ),
        (
            "9eamof",
            [
                ("button.t80_omni_relocate", SetRelocationState()),
                (
                    "button.t80_omni_reset_main_brush_lifespan",
                    ResetLifeSpan(LifeSpan.BRUSH),
                ),
                (
                    "button.t80_omni_reset_cleaning_solution_lifespan",
                    ResetLifeSpan(LifeSpan.CLEANING_SOLUTION),
                ),
                (
                    "button.t80_omni_reset_filter_lifespan",
                    ResetLifeSpan(LifeSpan.FILTER),
                ),
                (
                    "button.t80_omni_reset_hand_filter_lifespan",
                    ResetLifeSpan(LifeSpan.HAND_FILTER),
                ),
                (
                    "button.t80_omni_reset_sewage_box_lifespan",
                    ResetLifeSpan(LifeSpan.SEWAGE_BOX),
                ),
                (
                    "button.t80_omni_reset_side_brush_lifespan",
                    ResetLifeSpan(LifeSpan.SIDE_BRUSH),
                ),
                (
                    "button.t80_omni_reset_unit_care_lifespan",
                    ResetLifeSpan(LifeSpan.UNIT_CARE),
                ),
                (
                    "button.t80_omni_empty_dustbin",
                    station_action.StationAction(StationAction.EMPTY_DUSTBIN),
                ),
            ],
        ),
    ],
    ids=["yna5x1", "5xu9h3", "qhe2o2", "9eamof"],
)
async def test_buttons(
    hass: HomeAssistant,
    device_registry: dr.DeviceRegistry,
    entity_registry: er.EntityRegistry,
    snapshot: SnapshotAssertion,
    controller: EcovacsController,
    entities: list[tuple[str, Command]],
) -> None:
    """Test that sensor entity snapshots match."""
    assert hass.states.async_entity_ids() == [e[0] for e in entities]
    device = controller.devices[0]
    for entity_id, command in entities:
        assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
        assert state.state == STATE_UNKNOWN

        device._execute_command.reset_mock()
        await hass.services.async_call(
            BUTTON_DOMAIN,
            SERVICE_PRESS,
            {ATTR_ENTITY_ID: entity_id},
            blocking=True,
        )
        device._execute_command.assert_called_with(command)

        assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
        assert state.state == "2024-01-01T00:00:00+00:00"
        assert snapshot(name=f"{entity_id}:state") == state

        assert (entity_entry := entity_registry.async_get(state.entity_id))
        assert snapshot(name=f"{entity_id}:entity-registry") == entity_entry

        assert entity_entry.device_id
        assert (device_entry := device_registry.async_get(entity_entry.device_id))
        assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])}


@pytest.mark.parametrize(
    ("device_fixture", "entity_ids"),
    [
        (
            "yna5x1",
            [
                "button.ozmo_950_reset_main_brush_lifespan",
                "button.ozmo_950_reset_filter_lifespan",
                "button.ozmo_950_reset_side_brush_lifespan",
            ],
        ),
        (
            "5xu9h3",
            [
                "button.goat_g1_reset_blade_lifespan",
                "button.goat_g1_reset_lens_brush_lifespan",
            ],
        ),
    ],
)
async def test_disabled_by_default_buttons(
    hass: HomeAssistant, entity_registry: er.EntityRegistry, entity_ids: list[str]
) -> None:
    """Test the disabled by default buttons."""
    for entity_id in entity_ids:
        assert not hass.states.get(entity_id)

        assert (entry := entity_registry.async_get(entity_id)), (
            f"Entity registry entry for {entity_id} is missing"
        )
        assert entry.disabled
        assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
