from .entry_data import RuntimeEntryData as RuntimeEntryData
from aioesphomeapi import APIClient, APIIntEnum, APIVersion as APIVersion, DeviceInfo as EsphomeDeviceInfo, EntityInfo, EntityState, HomeassistantServiceCall as HomeassistantServiceCall, UserService as UserService
from collections.abc import Awaitable
from homeassistant import const as const
from homeassistant.components import zeroconf as zeroconf
from homeassistant.config_entries import ConfigEntry as ConfigEntry
from homeassistant.const import CONF_HOST as CONF_HOST, CONF_MODE as CONF_MODE, CONF_PASSWORD as CONF_PASSWORD, CONF_PORT as CONF_PORT, EVENT_HOMEASSISTANT_STOP as EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Event as Event, HomeAssistant as HomeAssistant, ServiceCall as ServiceCall, State as State, callback as callback
from homeassistant.exceptions import TemplateError as TemplateError
from homeassistant.helpers import template as template
from homeassistant.helpers.dispatcher import async_dispatcher_connect as async_dispatcher_connect
from homeassistant.helpers.entity import DeviceInfo as DeviceInfo, Entity as Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback as AddEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event as async_track_state_change_event
from homeassistant.helpers.json import JSONEncoder as JSONEncoder
from homeassistant.helpers.service import async_set_service_schema as async_set_service_schema
from homeassistant.helpers.storage import Store as Store
from homeassistant.helpers.template import Template as Template
from typing import Any, Callable, TypeVar, overload
from zeroconf import DNSRecord as DNSRecord, RecordUpdateListener, Zeroconf as Zeroconf

DOMAIN: str
_LOGGER: Any
_T = TypeVar('_T')
STORAGE_VERSION: int

class DomainData:
    _entry_datas: dict[str, RuntimeEntryData]
    _stores: dict[str, Store]
    def get_entry_data(self, entry: ConfigEntry) -> RuntimeEntryData: ...
    def set_entry_data(self, entry: ConfigEntry, entry_data: RuntimeEntryData) -> None: ...
    def pop_entry_data(self, entry: ConfigEntry) -> RuntimeEntryData: ...
    def is_entry_loaded(self, entry: ConfigEntry) -> bool: ...
    def get_or_create_store(self, hass: HomeAssistant, entry: ConfigEntry) -> Store: ...
    @classmethod
    def get(cls, hass: HomeAssistant) -> _T: ...

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ...

class ReconnectLogic(RecordUpdateListener):
    _hass: Any
    _cli: Any
    _entry: Any
    _host: Any
    _on_login: Any
    _zc: Any
    _connected: bool
    _connected_lock: Any
    _zc_lock: Any
    _zc_listening: bool
    _reconnect_event: Any
    _loop_task: Any
    _tries: int
    _tries_lock: Any
    _wait_task: Any
    _wait_task_lock: Any
    def __init__(self, hass: HomeAssistant, cli: APIClient, entry: ConfigEntry, host: str, on_login: Callable[[], Awaitable[None]], zc: Zeroconf) -> None: ...
    @property
    def _entry_data(self) -> Union[RuntimeEntryData, None]: ...
    async def _on_disconnect(self) -> None: ...
    async def _wait_and_start_reconnect(self) -> None: ...
    async def _try_connect(self) -> None: ...
    async def _reconnect_once(self) -> None: ...
    async def _reconnect_loop(self) -> None: ...
    async def start(self) -> None: ...
    async def stop(self) -> None: ...
    async def _start_zc_listen(self) -> None: ...
    async def _stop_zc_listen(self) -> None: ...
    def stop_callback(self) -> None: ...
    def _set_reconnect(self) -> None: ...
    def update_record(self, zc: Zeroconf, now: float, record: DNSRecord) -> None: ...

async def _async_setup_device_registry(hass: HomeAssistant, entry: ConfigEntry, device_info: EsphomeDeviceInfo) -> str: ...

ARG_TYPE_METADATA: Any

async def _register_service(hass: HomeAssistant, entry_data: RuntimeEntryData, service: UserService) -> None: ...
async def _setup_services(hass: HomeAssistant, entry_data: RuntimeEntryData, services: list[UserService]) -> None: ...
async def _cleanup_instance(hass: HomeAssistant, entry: ConfigEntry) -> RuntimeEntryData: ...
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ...
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: ...
_InfoT = TypeVar('_InfoT', bound=EntityInfo)
_EntityT = TypeVar('_EntityT', bound='EsphomeEntity[Any,Any]')
_StateT = TypeVar('_StateT', bound=EntityState)

async def platform_async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, component_key: str, info_type: type[_InfoT], entity_type: type[_EntityT], state_type: type[_StateT]) -> None: ...
_PropT = TypeVar('_PropT', bound=Callable[..., Any])

def esphome_state_property(func: _PropT) -> _PropT: ...
_EnumT = TypeVar('_EnumT', bound=APIIntEnum)
_ValT = TypeVar('_ValT')

class EsphomeEnumMapper:
    _mapping: Any
    _inverse: Any
    def __init__(self, mapping: dict[_EnumT, _ValT]) -> None: ...
    @overload
    def from_esphome(self, value: _EnumT) -> _ValT: ...
    @overload
    def from_esphome(self, value: Union[_EnumT, None]) -> Union[_ValT, None]: ...
    def from_hass(self, value: _ValT) -> _EnumT: ...

class EsphomeEntity(Entity):
    _entry_data: Any
    _component_key: Any
    _key: Any
    def __init__(self, entry_data: RuntimeEntryData, component_key: str, key: int) -> None: ...
    async def async_added_to_hass(self) -> None: ...
    def _on_state_update(self) -> None: ...
    def _on_device_update(self) -> None: ...
    @property
    def _entry_id(self) -> str: ...
    @property
    def _api_version(self) -> APIVersion: ...
    @property
    def _static_info(self) -> _InfoT: ...
    @property
    def _device_info(self) -> EsphomeDeviceInfo: ...
    @property
    def _client(self) -> APIClient: ...
    @property
    def _state(self) -> _StateT: ...
    @property
    def _has_state(self) -> bool: ...
    @property
    def available(self) -> bool: ...
    @property
    def unique_id(self) -> Union[str, None]: ...
    @property
    def device_info(self) -> DeviceInfo: ...
    @property
    def name(self) -> str: ...
    @property
    def should_poll(self) -> bool: ...
