from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, Optional


class RegistryRemediation:
    """Track and restore registry values with explicit rollback metadata."""

    def __init__(self, registry_path: str | Path):
        self.registry_path = Path(registry_path)
        self.registry_path.parent.mkdir(parents=True, exist_ok=True)
        if not self.registry_path.exists():
            self.registry_path.write_text("{}", encoding="utf-8")
        self._backup_store = self.registry_path.parent / "registry_backup.json"

    def load_registry(self) -> Dict[str, Dict[str, Any]]:
        try:
            payload = json.loads(self.registry_path.read_text(encoding="utf-8"))
        except (json.JSONDecodeError, OSError):
            payload = {}
        return payload if isinstance(payload, dict) else {}

    def capture_snapshot(self) -> Dict[str, Any]:
        current = self.load_registry()
        self._backup_store.write_text(json.dumps(current, indent=2, sort_keys=True), encoding="utf-8")
        return {"before_state": current, "backup_path": str(self._backup_store)}

    def set_value(self, key: str, value_name: str, value: Any) -> Dict[str, Any]:
        data = self.load_registry()
        if key not in data:
            data[key] = {}
        self.capture_snapshot()
        data[key][value_name] = value
        self._write_registry(data)
        return {"key": key, "value_name": value_name, "status": "updated", "value": value}

    def restore_value(self, key: str, value_name: str) -> Dict[str, Any]:
        if self._backup_store.exists():
            backup = json.loads(self._backup_store.read_text(encoding="utf-8"))
            if isinstance(backup, dict) and key in backup and value_name in backup[key]:
                data = self.load_registry()
                data[key] = backup[key]
                self._write_registry(data)
                return {"key": key, "value_name": value_name, "status": "restored", "value": backup[key][value_name]}

        data = self.load_registry()
        if key not in data or value_name not in data[key]:
            return {"key": key, "value_name": value_name, "status": "missing"}
        del data[key][value_name]
        self._write_registry(data)
        return {"key": key, "value_name": value_name, "status": "restored", "value": None}

    def _write_registry(self, data: Dict[str, Dict[str, Any]]) -> None:
        self.registry_path.write_text(json.dumps(data, indent=2, sort_keys=True), encoding="utf-8")
