"""Type stub file for States resource.

This stub provides static type hints for all known domain properties on the States
class, enabling IDE autocomplete and type checking. At runtime, these properties are
handled by __getattr__ in states.py, which queries the state registry dynamically.

For custom domains not listed here, users should use:
```python
    app.states[CustomStateClass]
```

As this will ensure proper type annotations of the return type.
"""

import typing
from collections.abc import Iterator
from typing import Generic, NamedTuple

from frozendict import frozendict

from hassette.conversion import StateKey
from hassette.models import states
from hassette.resources.base import Resource
from hassette.types import StateT

if typing.TYPE_CHECKING:
    from hassette import Hassette
    from hassette.core.state_proxy import StateProxy
    from hassette.events import HassStateDict

class CacheValue(Generic[StateT], NamedTuple):
    context_id: str | None
    frozen_state: frozendict
    model: StateT

class DomainStates(typing.Generic[StateT]):
    _state_proxy: StateProxy
    _model: type[StateT]
    _domain: str
    _cache: dict[str, CacheValue[StateT]]

    def _validate_or_return_from_cache(self, entity_id: str, state: HassStateDict) -> StateT: ...
    def __init__(self, state_proxy: StateProxy, model: type[StateT]) -> None: ...
    def __iter__(self) -> typing.Generator[tuple[str, StateT], typing.Any, None]: ...
    def __len__(self) -> int: ...
    def __getitem__(self, entity_id: str) -> StateT: ...
    def __contains__(self, entity_id: str) -> bool: ...
    def __repr__(self) -> str: ...
    def __bool__(self) -> bool: ...
    def get(self, entity_id: str) -> StateT | None: ...
    def items(self) -> Iterator[tuple[str, StateT]]: ...
    def keys(self) -> list[str]: ...
    def iterkeys(self) -> typing.Iterator[str]: ...
    def values(self) -> list[StateT]: ...
    def itervalues(self) -> Iterator[StateT]: ...
    def to_dict(self) -> dict[str, StateT]: ...

class StateManager(Resource):
    @property
    def _state_proxy(self) -> StateProxy: ...
    @classmethod
    def create(cls, hassette: Hassette, parent: Resource) -> StateManager: ...

    # Known domain properties with full typing
    @property
    def ai_task(self) -> DomainStates[states.AiTaskState]: ...
    @property
    def air_quality(self) -> DomainStates[states.AirQualityState]: ...
    @property
    def alarm_control_panel(self) -> DomainStates[states.AlarmControlPanelState]: ...
    @property
    def assist_satellite(self) -> DomainStates[states.AssistSatelliteState]: ...
    @property
    def automation(self) -> DomainStates[states.AutomationState]: ...
    @property
    def binary_sensor(self) -> DomainStates[states.BinarySensorState]: ...
    @property
    def button(self) -> DomainStates[states.ButtonState]: ...
    @property
    def calendar(self) -> DomainStates[states.CalendarState]: ...
    @property
    def camera(self) -> DomainStates[states.CameraState]: ...
    @property
    def climate(self) -> DomainStates[states.ClimateState]: ...
    @property
    def conversation(self) -> DomainStates[states.ConversationState]: ...
    @property
    def cover(self) -> DomainStates[states.CoverState]: ...
    @property
    def date(self) -> DomainStates[states.DateState]: ...
    @property
    def datetime(self) -> DomainStates[states.DateTimeState]: ...
    @property
    def device_tracker(self) -> DomainStates[states.DeviceTrackerState]: ...
    @property
    def event(self) -> DomainStates[states.EventState]: ...
    @property
    def fan(self) -> DomainStates[states.FanState]: ...
    @property
    def humidifier(self) -> DomainStates[states.HumidifierState]: ...
    @property
    def image_processing(self) -> DomainStates[states.ImageProcessingState]: ...
    @property
    def input_boolean(self) -> DomainStates[states.InputBooleanState]: ...
    @property
    def input_button(self) -> DomainStates[states.InputButtonState]: ...
    @property
    def input_datetime(self) -> DomainStates[states.InputDatetimeState]: ...
    @property
    def input_number(self) -> DomainStates[states.InputNumberState]: ...
    @property
    def input_select(self) -> DomainStates[states.InputSelectState]: ...
    @property
    def input_text(self) -> DomainStates[states.InputTextState]: ...
    @property
    def light(self) -> DomainStates[states.LightState]: ...
    @property
    def lock(self) -> DomainStates[states.LockState]: ...
    @property
    def media_player(self) -> DomainStates[states.MediaPlayerState]: ...
    @property
    def notify(self) -> DomainStates[states.NotifyState]: ...
    @property
    def number(self) -> DomainStates[states.NumberState]: ...
    @property
    def person(self) -> DomainStates[states.PersonState]: ...
    @property
    def remote(self) -> DomainStates[states.RemoteState]: ...
    @property
    def scene(self) -> DomainStates[states.SceneState]: ...
    @property
    def script(self) -> DomainStates[states.ScriptState]: ...
    @property
    def select(self) -> DomainStates[states.SelectState]: ...
    @property
    def sensor(self) -> DomainStates[states.SensorState]: ...
    @property
    def siren(self) -> DomainStates[states.SirenState]: ...
    @property
    def stt(self) -> DomainStates[states.SttState]: ...
    @property
    def sun(self) -> DomainStates[states.SunState]: ...
    @property
    def switch(self) -> DomainStates[states.SwitchState]: ...
    @property
    def text(self) -> DomainStates[states.TextState]: ...
    @property
    def time(self) -> DomainStates[states.TimeState]: ...
    @property
    def timer(self) -> DomainStates[states.TimerState]: ...
    @property
    def todo(self) -> DomainStates[states.TodoState]: ...
    @property
    def tts(self) -> DomainStates[states.TtsState]: ...
    @property
    def update(self) -> DomainStates[states.UpdateState]: ...
    @property
    def vacuum(self) -> DomainStates[states.VacuumState]: ...
    @property
    def valve(self) -> DomainStates[states.ValveState]: ...
    @property
    def water_heater(self) -> DomainStates[states.WaterHeaterState]: ...
    @property
    def weather(self) -> DomainStates[states.WeatherState]: ...
    @property
    def zone(self) -> DomainStates[states.ZoneState]: ...
    def __getitem__(self, model: type[StateT]) -> DomainStates[StateT]: ...
    def __contains__(self, model: type[StateT]) -> bool: ...
    def __iter__(self) -> Iterator[tuple[StateKey, DomainStates[states.BaseState]]]: ...
    def items(self) -> Iterator[tuple[StateKey, DomainStates[states.BaseState]]]: ...
    def values(self) -> Iterator[DomainStates[states.BaseState]]: ...
    def keys(self) -> Iterator[StateKey]: ...
