"""Persona 解析 — session override · OT4 · detach。"""

from __future__ import annotations

from pathlib import Path
from typing import Any

from niannian.cognitive.persona_registry import (
    PersonaPack,
    PersonaRegistry,
    persona_registry_for_user,
    resolve_persona_pack,
)
from niannian.object.tenant import ObjectTenantStore


class PersonaResolver:
    def __init__(self, config: dict[str, Any], *, home: Path, user_id: str = "pinn") -> None:
        self._config = config
        self._home = home
        self._user_id = user_id
        self._registry = persona_registry_for_user(home, user_id, config)
        self._objects = ObjectTenantStore(home, user_id=user_id)

    def resolve(
        self,
        session_meta: dict[str, Any] | None,
        *,
        object_id: str | None = None,
    ) -> PersonaPack:
        meta = dict(session_meta or {})
        equipped_vp_id = meta.get("equipped_vp_id")
        if equipped_vp_id is not None and str(equipped_vp_id).strip():
            if self._registry.exists():
                return self._registry.build_persona_pack(self._registry.detach_preset_id())
            return resolve_persona_pack("plain", self._config, home=self._home)
        override = meta.get("persona_override")
        preset_id: str | None = None

        if isinstance(override, dict):
            raw = override.get("preset")
            if raw is not None:
                preset_id = str(raw).strip() or None
            if preset_id and override.get("mode") == "remember" and object_id:
                self._objects.save_persona(object_id, {"default_preset": preset_id})
        elif object_id:
            persona_doc = self._objects.load_persona(object_id)
            default = persona_doc.get("default_preset")
            if default is not None and str(default).strip():
                preset_id = str(default).strip()

        if not self._registry.exists():
            return resolve_persona_pack(preset_id, self._config, home=self._home)
        return self._registry.build_persona_pack(preset_id)

    def resolve_preset_id(
        self,
        session_meta: dict[str, Any] | None,
        *,
        object_id: str | None = None,
    ) -> str | None:
        pack = self.resolve(session_meta, object_id=object_id)
        if pack.detached:
            return None
        return pack.preset_id
