from __future__ import annotations

import logging
from datetime import timedelta

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .api import SeaTemperatureAPI
from .const import (
    CONF_AREA,
    CONF_CONTINENT,
    CONF_COUNTRY,
    CONF_PATH,
    CONF_PLACE,
    CONF_PLACE_ID,
    DOMAIN,
)

PLATFORMS = [Platform.SENSOR]
SCAN_INTERVAL = timedelta(hours=2)  # Sea temperatures don't change frequently
_LOGGER = logging.getLogger(__name__)


async def async_setup(hass: HomeAssistant, config: dict) -> bool:
    """Set up the Sea Temperatures component."""
    from homeassistant.loader import async_get_integration

    integration = await async_get_integration(hass, DOMAIN)
    version = integration.version or "1.0.0"

    # Register static path for the card
    from homeassistant.components.http import StaticPathConfig

    await hass.http.async_register_static_paths(
        [
            StaticPathConfig(
                url_path="/seatemperatures_frontend/sea-temperatures-card.js",
                path=hass.config.path(
                    "custom_components/seatemperatures/sea-temperatures-card.js"
                ),
                cache_headers=True,
            )
        ]
    )
    new_url = f"/seatemperatures_frontend/sea-temperatures-card.js?v={version}"

    async def _async_register_lovelace_resource(event=None):
        _LOGGER.debug("Attempting to register lovelace resource")
        if "lovelace" not in hass.data:
            _LOGGER.warning("Lovelace not found in hass.data")
            return

        lovelace_data = hass.data["lovelace"]
        mode = getattr(lovelace_data, "resource_mode", "storage")
        resources = getattr(lovelace_data, "resources", None)

        if not resources:
            _LOGGER.warning("Lovelace data does not have resources")
            return

        if mode != "storage":
            _LOGGER.warning(
                "Lovelace is not in storage mode (mode is '%s'), cannot auto-register",
                mode,
            )
            return

        # Check if resource is already registered
        for item in resources.async_items():
            if item.get("url", "").startswith("/seatemperatures_frontend/"):
                if item.get("url") != new_url:
                    _LOGGER.debug("Updating lovelace resource URL to %s", new_url)
                    await resources.async_update_item(item.get("id"), {"url": new_url})
                return

        # Not registered, add it
        try:
            _LOGGER.info("Registering lovelace resource: %s", new_url)
            await resources.async_create_item({"res_type": "module", "url": new_url})
        except Exception as e:  # noqa: BLE001 - resource registration must never break setup
            _LOGGER.warning("Failed to register lovelace resource: %s", e)

    from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
    from homeassistant.core import CoreState

    if hass.state == CoreState.running:
        hass.async_create_task(_async_register_lovelace_resource())
    else:
        hass.bus.async_listen_once(
            EVENT_HOMEASSISTANT_STARTED, _async_register_lovelace_resource
        )

    return True


async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Migrate legacy config entries from place IDs to path-based locations."""
    if entry.version > 2:
        _LOGGER.error("Unsupported SeaTemperatures config entry version: %s", entry.version)
        return False

    if entry.version < 2:
        _LOGGER.debug("Migrating SeaTemperatures entry %s from version %s", entry.entry_id, entry.version)

        data = dict(entry.data)
        location_path = data.get(CONF_PATH)
        if not location_path:
            place_id = data.get(CONF_PLACE_ID)
            if not place_id:
                _LOGGER.error(
                    "SeaTemperatures entry %s has no place_id to migrate. Remove and re-add the integration.",
                    entry.entry_id,
                )
                return False

            location = await SeaTemperatureAPI(hass).get_location_by_place_id(place_id)
            if location is None:
                _LOGGER.error(
                    "SeaTemperatures place_id %s could not be mapped to a current location path. Remove and re-add the integration.",
                    place_id,
                )
                return False

            data[CONF_PATH] = location[CONF_PATH]
            data[CONF_PLACE] = location.get("name", data.get(CONF_PLACE, "Unknown"))
            data[CONF_COUNTRY] = location.get(CONF_COUNTRY, data.get(CONF_COUNTRY, ""))
            data[CONF_AREA] = location.get(CONF_AREA, data.get(CONF_AREA, ""))
            data.setdefault(CONF_CONTINENT, data.get(CONF_CONTINENT, ""))

        hass.config_entries.async_update_entry(
            entry,
            data=data,
            unique_id=data[CONF_PATH],
            version=2,
        )

    return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Sea Temperature from a config entry."""
    hass.data.setdefault(DOMAIN, {})

    place_name = entry.data.get(CONF_PLACE, "Unknown")
    location_path = entry.data.get(CONF_PATH)
    location_key = entry.data.get(CONF_PLACE_ID) or location_path or entry.entry_id

    api = SeaTemperatureAPI(hass)

    async def async_update_data():
        """Fetch data from API."""
        if not location_path:
            raise UpdateFailed(
                "No location path configured. Remove and re-add the integration."
            )

        data = await api.get_temperatures(location_path)
        if not data:
            raise UpdateFailed(f"Failed to fetch data for place {place_name}")

        return data

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=f"seatemperatures_{location_key}",
        update_method=async_update_data,
        update_interval=SCAN_INTERVAL,
    )

    await coordinator.async_config_entry_first_refresh()

    hass.data[DOMAIN][entry.entry_id] = coordinator

    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."""
    if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
        hass.data[DOMAIN].pop(entry.entry_id)

    return unload_ok
