"""DMNRunner — dream 后维护 open_threads（SL7）。"""

from __future__ import annotations

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

from niannian.personas import DMN
from niannian.soul.subject_store import SubjectStateStore


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


class DMNRunner:
    def __init__(self, config: dict[str, Any] | None = None) -> None:
        self._config = config or {}
        soul = self._config.get("soul") or {}
        dmn_cfg = soul.get("dmn") or {}
        self._max_threads = int(dmn_cfg.get("max_open_threads", 8))

    def after_dream(
        self,
        store: SubjectStateStore,
        *,
        subject_atom_ids: list[str] | None = None,
    ) -> dict[str, Any]:
        trace: list[str] = []
        threads = store.load_open_threads()
        touched = 0
        ids = list(subject_atom_ids or [])

        if not threads and ids:
            theme = f"待续：整理 {len(ids)} 条主体记忆"
            threads.append(
                {
                    "id": uuid4().hex[:12],
                    "theme": theme,
                    "priority": "normal",
                    "source": "dmn",
                    "source_atom_ids": ids[:5],
                    "updated_at": _now_iso(),
                }
            )
            touched = 1
            trace.append(f"[{DMN}] seeded open_thread from dream atoms={len(ids)}")
        else:
            for thread in threads[: self._max_threads]:
                if not isinstance(thread, dict):
                    continue
                thread["last_dream_at"] = _now_iso()
                touched += 1
            if touched:
                trace.append(f"[{DMN}] refreshed {touched} open_threads")

        if touched:
            store.save_open_threads(threads)

        return {"threads_touched": touched, "open_threads_count": len(threads), "trace": trace}

    @staticmethod
    def trace_line(msg: str) -> str:
        return f"[{DMN}] {msg}"
