"""SL8 纠偏锚点 — authorized_baseline 快照与恢复。"""

from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from uuid import uuid4

import yaml

from niannian.soul.subject_store import SubjectStateStore


def _now_iso() -> str:
    return datetime.now(timezone.utc).isoformat()


class BaselineManager:
    """SL8：identity + values 快照；纠偏 restore。"""

    def __init__(self, store: SubjectStateStore) -> None:
        self._store = store
        self._root = store.subject_root / "authorized_baseline"

    def list_snapshots(self) -> list[dict[str, Any]]:
        rows: list[dict[str, Any]] = []
        if not self._root.is_dir():
            return rows
        for meta_path in sorted(self._root.glob("*/meta.json")):
            try:
                with meta_path.open(encoding="utf-8") as f:
                    row = json.load(f)
                if isinstance(row, dict):
                    rows.append(row)
            except (json.JSONDecodeError, OSError):
                continue
        return sorted(rows, key=lambda r: r.get("created_at", ""), reverse=True)

    def snapshot(self, *, label: str | None = None) -> Path:
        snap_id = uuid4().hex[:12]
        dest = self._root / snap_id
        dest.mkdir(parents=True, exist_ok=True)

        identity = self._store.load_identity()
        values = self._store.load_values()
        (dest / "identity.yaml").write_text(
            yaml.safe_dump(identity, allow_unicode=True, sort_keys=False),
            encoding="utf-8",
        )
        (dest / "values.yaml").write_text(
            yaml.safe_dump(values, allow_unicode=True, sort_keys=False),
            encoding="utf-8",
        )
        meta = {
            "id": snap_id,
            "label": label or "baseline",
            "created_at": _now_iso(),
            "identity_name": identity.get("name"),
            "values_version": values.get("version"),
        }
        (dest / "meta.json").write_text(json.dumps(meta, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
        return dest

    def restore(self, snapshot_id: str) -> dict[str, Any]:
        src = self._root / snapshot_id
        if not src.is_dir():
            raise FileNotFoundError(f"baseline not found: {snapshot_id}")

        identity_path = self._store.subject_root / "identity.yaml"
        values_path = self._store.subject_root / "values.yaml"

        id_src = src / "identity.yaml"
        val_src = src / "values.yaml"
        if not id_src.is_file() or not val_src.is_file():
            raise FileNotFoundError(f"baseline incomplete: {snapshot_id}")

        identity_path.write_text(id_src.read_text(encoding="utf-8"), encoding="utf-8")
        values_path.write_text(val_src.read_text(encoding="utf-8"), encoding="utf-8")
        return {
            "restored": snapshot_id,
            "identity": self._store.load_identity(),
            "values": self._store.load_values(),
        }
