"""One-shot migration: legacy global ``MQTTConfig`` (YAML/env) → first ``MQTTSource``.

Pre-multi-broker, LedGrab had a single MQTT broker configured under
``mqtt:`` in ``config.yaml`` (and ``LEDGRAB_MQTT__*`` env vars). After the
multi-broker refactor those settings are no longer read at runtime — every
consumer references an ``MQTTSource`` id.

To avoid silently dropping the legacy broker config when upgrading, this
migrator runs once at startup. If the source store is empty AND the
legacy YAML/env values look configured (broker_host set or ``enabled=true``),
it creates a single :class:`MQTTSource` named "Default Broker" from those
values. After the first run nothing happens — the store is the source of
truth.
"""

from __future__ import annotations

import os
from pathlib import Path

import yaml

from ledgrab.storage.mqtt_source_store import MQTTSourceStore
from ledgrab.utils import get_logger

logger = get_logger(__name__)


def _legacy_mqtt_from_env() -> dict | None:
    """Read legacy ``LEDGRAB_MQTT__*`` env vars (pydantic-settings convention)."""
    enabled = os.environ.get("LEDGRAB_MQTT__ENABLED", "").strip().lower()
    host = os.environ.get("LEDGRAB_MQTT__BROKER_HOST", "").strip()
    if not host and enabled not in ("true", "1", "yes"):
        return None
    return {
        "enabled": enabled in ("true", "1", "yes"),
        "broker_host": host or "localhost",
        "broker_port": int(os.environ.get("LEDGRAB_MQTT__BROKER_PORT", "1883") or "1883"),
        "username": os.environ.get("LEDGRAB_MQTT__USERNAME", "") or "",
        "password": os.environ.get("LEDGRAB_MQTT__PASSWORD", "") or "",
        "client_id": os.environ.get("LEDGRAB_MQTT__CLIENT_ID", "ledgrab") or "ledgrab",
        "base_topic": os.environ.get("LEDGRAB_MQTT__BASE_TOPIC", "ledgrab") or "ledgrab",
    }


def _candidate_config_paths() -> list[Path]:
    """Yield the YAML files that might hold the legacy ``mqtt:`` block."""
    paths: list[Path] = []
    override = os.environ.get("LEDGRAB_CONFIG_PATH")
    if override:
        paths.append(Path(override))
    if os.environ.get("LEDGRAB_DEMO", "").lower() in ("true", "1", "yes"):
        paths.append(Path("config/demo_config.yaml"))
    paths.append(Path("config/default_config.yaml"))
    return paths


def _legacy_mqtt_from_yaml() -> dict | None:
    """Read legacy ``mqtt:`` block from the platform config.yaml."""
    for path in _candidate_config_paths():
        if not path.is_file():
            continue
        try:
            with open(path, "r", encoding="utf-8") as f:
                doc = yaml.safe_load(f) or {}
        except Exception as e:
            logger.debug("Could not read %s for MQTT migration: %s", path, e)
            continue
        block = doc.get("mqtt") if isinstance(doc, dict) else None
        if isinstance(block, dict):
            host = (block.get("broker_host") or "").strip()
            enabled = bool(block.get("enabled"))
            if host or enabled:
                return {
                    "enabled": enabled,
                    "broker_host": host or "localhost",
                    "broker_port": int(block.get("broker_port") or 1883),
                    "username": str(block.get("username") or ""),
                    "password": str(block.get("password") or ""),
                    "client_id": str(block.get("client_id") or "ledgrab"),
                    "base_topic": str(block.get("base_topic") or "ledgrab"),
                }
    return None


def migrate_legacy_mqtt_config(store: MQTTSourceStore) -> None:
    """Seed a "Default Broker" :class:`MQTTSource` if the store is empty
    and a legacy YAML/env MQTT config is detected.

    Idempotent: if the store already has any sources, this is a no-op.
    Logs a deprecation warning when migration runs.
    """
    if store.count() > 0:
        return

    legacy = _legacy_mqtt_from_env() or _legacy_mqtt_from_yaml()
    if legacy is None:
        return

    try:
        source = store.create_source(
            name="Default Broker",
            broker_host=legacy["broker_host"],
            broker_port=legacy["broker_port"],
            username=legacy["username"],
            password=legacy["password"],
            client_id=legacy["client_id"],
            base_topic=legacy["base_topic"],
            description="Migrated from legacy mqtt: config block",
        )
    except Exception as e:
        logger.error("Failed to migrate legacy MQTT config: %s", e)
        return

    logger.warning(
        "Migrated legacy MQTT config to source %s (%s:%d). "
        "The 'mqtt:' YAML block and LEDGRAB_MQTT__* env vars are no longer "
        "read; edit the broker in the UI under MQTT Sources from now on.",
        source.id,
        source.broker_host,
        source.broker_port,
    )
