"""Handle temps.command payloads (runtime sensor setup)."""

from __future__ import annotations

import logging
from typing import Any

from .config import TempConfig
from .runtime import TempRuntime
from .identity import backup_probe_map, clear_probe_map, restore_probe_map

logger = logging.getLogger("hot_tub.temp")


class TempCommandError(ValueError):
    pass


def apply_temp_command(
    cfg: TempConfig,
    runtime: TempRuntime,
    envelope: dict[str, Any],
) -> None:
    op = envelope.get("op")
    if not op or not isinstance(op, str):
        raise TempCommandError("missing or invalid op")

    path = cfg.probe_map_path

    if op == "setup_start":
        backup_probe_map(path)
        clear_probe_map(path)
        runtime.setup_mode_override = True
        runtime.setup_active = True
        logger.info("sensor setup started (probe map cleared, backup saved)")
        return

    if op == "setup_finish":
        if runtime.last_setup_state != "ready":
            raise TempCommandError(
                f"setup_finish requires setup_state ready (got {runtime.last_setup_state!r})"
            )
        runtime.setup_mode_override = False
        runtime.setup_active = False
        logger.info("sensor setup finished")
        return

    if op == "setup_cancel":
        restore_probe_map(path)
        runtime.setup_mode_override = False
        runtime.setup_active = False
        logger.info("sensor setup cancelled (probe map restored)")
        return

    raise TempCommandError(f"unknown op: {op!r}")


def parse_command_message(raw: str) -> dict[str, Any]:
    import json

    try:
        data = json.loads(raw)
    except json.JSONDecodeError as exc:
        raise TempCommandError("invalid JSON") from exc
    if not isinstance(data, dict):
        raise TempCommandError("command must be a JSON object")
    return data
