"""VP 装填时的 chat_mode 门禁 — companion/work/auto 仅允许。"""

from __future__ import annotations

from typing import Any

VP_ALLOWED_CHAT_MODES = frozenset({"companion", "work", "auto"})
VP_FORBIDDEN_CHAT_MODES = frozenset({"default", "education"})


class VpChatModeForbiddenError(ValueError):
    """装填 VP 时 chat_mode 不在允许集合内。"""


def has_equipped_vp(meta: dict[str, Any]) -> bool:
    vp_id = meta.get("equipped_vp_id")
    return vp_id is not None and bool(str(vp_id).strip())


def effective_session_chat_mode(meta: dict[str, Any]) -> str:
    raw = meta.get("chat_mode")
    if raw is not None and str(raw).strip():
        return str(raw).strip().lower()
    lock = str(meta.get("regime_lock") or "").strip().lower()
    if lock in VP_ALLOWED_CHAT_MODES or lock in VP_FORBIDDEN_CHAT_MODES:
        return lock
    return "auto"


def assert_chat_mode_allowed_for_vp(meta: dict[str, Any], chat_mode: str | None) -> None:
    if not has_equipped_vp(meta):
        return
    if chat_mode is None or not str(chat_mode).strip():
        return
    mode = str(chat_mode).strip().lower()
    if mode in VP_FORBIDDEN_CHAT_MODES or mode not in VP_ALLOWED_CHAT_MODES:
        raise VpChatModeForbiddenError(
            f"chat_mode {mode!r} not allowed with equipped virtual persona; "
            f"use companion, work, or auto"
        )


def assert_session_chat_mode_allowed_for_vp(meta: dict[str, Any]) -> None:
    if not has_equipped_vp(meta):
        return
    mode = effective_session_chat_mode(meta)
    assert_chat_mode_allowed_for_vp(meta, mode)


def assert_session_ready_for_vp_equip(meta: dict[str, Any]) -> None:
    """装填 VP 前校验当前 session chat_mode 与 VP 兼容。"""
    mode = effective_session_chat_mode(meta)
    if mode in VP_FORBIDDEN_CHAT_MODES or mode not in VP_ALLOWED_CHAT_MODES:
        raise VpChatModeForbiddenError(
            f"chat_mode {mode!r} not allowed with virtual persona; "
            f"use companion, work, or auto before equipping"
        )
