"""Greenhousino Irrigation integration."""

import logging

import voluptuous as vol

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr

from .const import (
    CONF_COMMAND_TOPIC,
    CONF_HOST,
    CONF_STATE_TOPIC,
    DEFAULT_COMMAND_TOPIC,
    DEFAULT_STATE_TOPIC,
    DOMAIN,
    MANUFACTURER,
    MODEL,
    SERVICE_DATA_DURATION,
    SERVICE_WATER_FOR,
)

_LOGGER = logging.getLogger(__name__)

PLATFORMS = ["switch"]

# Service schema
WATER_FOR_SCHEMA = vol.Schema(
    {
        vol.Required(SERVICE_DATA_DURATION): vol.All(
            vol.Coerce(float),
            vol.Range(min=1, max=3600),
        ),
    }
)


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Greenhousino from a config entry."""
    hass_data = entry.runtime_data = GreenhousinoData(entry)

    host = entry.data.get(CONF_HOST, "")

    # Register device in HA device registry
    await _register_device(hass, entry, host)

    # Store entry data for service access
    if DOMAIN not in hass.data:
        hass.data[DOMAIN] = {"entries": {}}

    hass.data[DOMAIN]["entries"][entry.entry_id] = hass_data

    # Register the water_for service (only once)
    if "service_registered" not in hass.data[DOMAIN]:
        hass.services.async_register(
            DOMAIN,
            SERVICE_WATER_FOR,
            _make_water_for_handler(hass),
            schema=WATER_FOR_SCHEMA,
        )
        hass.data[DOMAIN]["service_registered"] = True
        _LOGGER.info("Registered %s.%s service", DOMAIN, SERVICE_WATER_FOR)

    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

    return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Unload a config entry."""
    unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

    if unload_ok:
        hass.data[DOMAIN]["entries"].pop(entry.entry_id, None)

        if len(hass.data[DOMAIN]["entries"]) == 0:
            hass.services.async_remove(DOMAIN, SERVICE_WATER_FOR)
            hass.data[DOMAIN].clear()

    return unload_ok


def _make_water_for_handler(hass: HomeAssistant):
    """Create the water_for service handler with hass in closure."""

    async def async_water_for(call) -> None:
        """Handle the water_for service call."""
        duration_seconds = call.data[SERVICE_DATA_DURATION]
        duration_ms = int(duration_seconds * 1000)

        # Use first available command topic (or default)
        entries = hass.data[DOMAIN].get("entries", {})
        command_topic = DEFAULT_COMMAND_TOPIC
        for entry_id, data in entries.items():
            command_topic = data.command_topic
            _LOGGER.info(
                "Watering for %d seconds (%d ms) on topic %s (entry: %s)",
                duration_seconds,
                duration_ms,
                command_topic,
                entry_id,
            )
            await hass.services.async_call(
                "mqtt",
                "publish",
                {
                    "topic": command_topic,
                    "payload": str(duration_ms),
                    "qos": 1,
                    "retain": False,
                },
                blocking=True,
            )

        if not entries:
            _LOGGER.warning("No Greenhousino entries configured")

    return async_water_for


async def _register_device(hass: HomeAssistant, entry: ConfigEntry, host: str):
    """Register the device in the device registry."""
    dr.async_get(hass).async_get_or_create(
        config_entry_id=entry.entry_id,
        connections=set(),
        identifiers={(DOMAIN, entry.entry_id)},
        manufacturer=MANUFACTURER,
        model=MODEL,
        name=entry.title,
        configuration_url=f"http://{host}" if host else None,
    )


class GreenhousinoData:
    """Container for integration data."""

    def __init__(self, entry: ConfigEntry) -> None:
        self.entry = entry
        self.command_topic = entry.data.get(
            CONF_COMMAND_TOPIC, DEFAULT_COMMAND_TOPIC
        )
        self.state_topic = entry.data.get(CONF_STATE_TOPIC, DEFAULT_STATE_TOPIC)
