"""VP perfect-distill — preview export bundle contents (M1: no disk write)."""

from __future__ import annotations

import json
import re
from typing import TYPE_CHECKING, Any

from niannian.virtual_persona.assembly_master import (
    PROACTIVE_ASSEMBLY_EXCERPT_MAX,
    read_assembly_master,
    truncate_assembly_excerpt,
)
from niannian.virtual_persona.deep_learn import DEEP_LEARN_DIR, RUNS_DIR
from niannian.virtual_persona.desensitize import build_public_summary
from niannian.virtual_persona.stage import get_stage

if TYPE_CHECKING:
    from niannian.virtual_persona.store import VirtualPersonaStore

PERFECT_DISTILL_STAGES = frozenset({"daily", "perfect"})

EXPORT_OPTION_KEYS: tuple[str, ...] = (
    "include_full_l2",
    "include_stickers",
    "include_proactive_profile",
    "include_deep_learn_runs",
)

DEFAULT_EXPORT_OPTIONS: dict[str, bool] = {key: False for key in EXPORT_OPTION_KEYS}

_SECRET_PATTERNS: tuple[re.Pattern[str], ...] = (
    re.compile(r"(?i)(api[_-]?key|secret|token|password)\s*[:=]\s*\S+"),
    re.compile(r"\bsk-[a-zA-Z0-9]{20,}\b"),
    re.compile(r"(?i)bearer\s+[a-zA-Z0-9._\-]+"),
)


class PerfectDistillError(ValueError):
    """Illegal perfect-distill operation for current VP stage or state."""


def stage_allows_perfect_distill(stage: str) -> bool:
    return str(stage or "").strip() in PERFECT_DISTILL_STAGES


def normalize_export_options(raw: dict[str, Any] | None) -> dict[str, bool]:
    opts = dict(DEFAULT_EXPORT_OPTIONS)
    if not raw:
        return opts
    for key in EXPORT_OPTION_KEYS:
        if key in raw:
            opts[key] = bool(raw[key])
    return opts


def _strip_secrets(value: Any) -> Any:
    if isinstance(value, str):
        redacted = value
        for pattern in _SECRET_PATTERNS:
            redacted = pattern.sub("[REDACTED]", redacted)
        return redacted
    if isinstance(value, dict):
        out: dict[str, Any] = {}
        for k, v in value.items():
            key = str(k)
            if re.search(r"(?i)(api[_-]?key|secret|token|password)", key):
                out[key] = "[REDACTED]"
            else:
                out[key] = _strip_secrets(v)
        return out
    if isinstance(value, list):
        return [_strip_secrets(item) for item in value]
    return value


def _load_proactive_profile(store: VirtualPersonaStore, vp_id: str) -> dict[str, Any] | None:
    path = store.proactive_profile_path(vp_id)
    if not path.is_file():
        return None
    with path.open(encoding="utf-8") as f:
        data = json.load(f)
    if not isinstance(data, dict):
        return None
    return _strip_secrets(data)


def _load_deep_learn_runs(store: VirtualPersonaStore, vp_id: str) -> list[dict[str, Any]]:
    runs_dir = store.vp_dir(vp_id) / DEEP_LEARN_DIR / RUNS_DIR
    if not runs_dir.is_dir():
        return []
    rows: list[dict[str, Any]] = []
    for path in sorted(runs_dir.glob("*.json")):
        try:
            with path.open(encoding="utf-8") as f:
                run = json.load(f)
        except (OSError, json.JSONDecodeError):
            continue
        if not isinstance(run, dict):
            continue
        rows.append(
            _strip_secrets(
                {
                    "run_id": path.stem,
                    "task_id": run.get("task_id"),
                    "topic": run.get("topic"),
                    "summary": run.get("summary"),
                    "completed_at": run.get("completed_at"),
                }
            )
        )
    return rows


def _load_sticker_preview(store: VirtualPersonaStore, vp_id: str) -> list[dict[str, Any]]:
    from niannian.virtual_persona.stickers import list_vp_stickers

    rows: list[dict[str, Any]] = []
    for row in list_vp_stickers(store, vp_id):
        rows.append(
            {
                "slug": row.get("slug"),
                "label": row.get("label"),
                "source": row.get("source"),
                "triggers": list(row.get("triggers") or []),
            }
        )
    return rows


def build_perfect_distill_preview(
    store: VirtualPersonaStore,
    vp_id: str,
    export_options: dict[str, Any] | None = None,
) -> dict[str, Any]:
    """Build perfect-distill preview. Does not write export_bundle to disk."""
    stage = get_stage(store, vp_id)
    if not stage_allows_perfect_distill(stage):
        raise PerfectDistillError(
            f"perfect-distill requires stage daily or perfect, got {stage!r}"
        )

    opts = normalize_export_options(export_options)
    row = store.get(vp_id)
    assembly_text = read_assembly_master(store, vp_id)
    assembly_summary = truncate_assembly_excerpt(
        assembly_text,
        max_chars=PROACTIVE_ASSEMBLY_EXCERPT_MAX,
    )

    preview: dict[str, Any] = {
        "vp_id": vp_id,
        "label": row.get("label") or vp_id,
        "stage": stage,
        "export_options": opts,
        "profile_md": _strip_secrets(str(row.get("profile_md") or "")),
        "assembly_summary": _strip_secrets(assembly_summary),
        "public_summary": build_public_summary(store, vp_id),
    }

    if opts["include_full_l2"]:
        preview["assembly_master"] = _strip_secrets(assembly_text)
    if opts["include_stickers"]:
        preview["stickers"] = _load_sticker_preview(store, vp_id)
    if opts["include_proactive_profile"]:
        proactive = _load_proactive_profile(store, vp_id)
        if proactive is not None:
            preview["proactive_profile"] = proactive
    if opts["include_deep_learn_runs"]:
        preview["deep_learn_runs"] = _load_deep_learn_runs(store, vp_id)

    return {
        "bundle_id": None,
        "preview": preview,
    }
