"""Shared loader for health plans and spiritual plans.

Reads config/health-plans/ and config/spiritual-plans/.
Used by CLI, feed/roster, and Vastian Config tab.

Wave 7 — Saturn Integration.
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml


def _get_config_root() -> Path:
    """Project root containing config/."""
    return Path(__file__).resolve().parents[2]


def _config_dir() -> Path:
    from vastian.storage.data_root import get_config_dir

    return get_config_dir(_get_config_root())


def list_health_plans() -> list[str]:
    """List available health plan names (excluding template.yaml, _schema, and examples/)."""
    plans_dir = _config_dir() / "health-plans"
    names: list[str] = []
    if not plans_dir.exists():
        return names
    # Only scan the root directory — examples/ are developer reference, not user content
    for f in plans_dir.glob("*.yaml"):
        if f.stem.startswith("_"):
            continue
        if f.stem == "template":
            continue
        names.append(f.stem)
    return sorted(set(names))


def list_spiritual_plans() -> list[str]:
    """List available spiritual plan names (excluding template.yaml)."""
    plans_dir = _config_dir() / "spiritual-plans"
    names: list[str] = []
    if not plans_dir.exists():
        return names
    for f in plans_dir.glob("*.yaml"):
        if f.stem.startswith("_"):
            continue
        if f.stem == "template":
            continue
        names.append(f.stem)
    return sorted(set(names))


def load_health_plan(name: str) -> dict[str, Any] | None:
    """Load a health plan by name. Returns None if not found."""
    path = _config_dir() / "health-plans" / f"{name}.yaml"
    if path.exists():
        try:
            data = yaml.safe_load(path.read_text(encoding="utf-8"))
            return data if data else {}
        except Exception:
            return None
    return None


def load_spiritual_plan(name: str) -> dict[str, Any] | None:
    """Load a spiritual plan by name. Returns None if not found."""
    path = _config_dir() / "spiritual-plans" / f"{name}.yaml"
    if path.exists():
        try:
            data = yaml.safe_load(path.read_text(encoding="utf-8"))
            return data if data else {}
        except Exception:
            return None
    return None


def _load_spiritual_taxonomy() -> dict[str, Any]:
    """Load taxonomy from config/spiritual-plans/_taxonomy.yaml."""
    path = _config_dir() / "spiritual-plans" / "_taxonomy.yaml"
    if not path.exists():
        return {}
    try:
        data = yaml.safe_load(path.read_text(encoding="utf-8"))
        return data if isinstance(data, dict) else {}
    except Exception:
        return {}


def load_spiritual_plans_by_taxonomy(
    bucket: str | None = None,
    overlay: str | None = None,
) -> list[dict[str, Any]]:
    """Load spiritual plans filtered by bucket and/or overlay.

    Args:
        bucket: Ascending, Integrated, or Grounding.
        overlay: Professional Mastery, Personal Empowerment, or Relationships & Polarity.

    Returns:
        List of full plan dicts matching the filter.
    """
    taxonomy = _load_spiritual_taxonomy()
    plan_ids = set()
    if bucket and taxonomy.get("buckets", {}).get(bucket, {}).get("plan_ids"):
        plan_ids.update(taxonomy["buckets"][bucket]["plan_ids"])
    if overlay and taxonomy.get("overlays", {}).get(overlay, {}).get("plan_ids"):
        if plan_ids:
            plan_ids &= set(taxonomy["overlays"][overlay]["plan_ids"])
        else:
            plan_ids.update(taxonomy["overlays"][overlay]["plan_ids"])
    if not plan_ids and not bucket and not overlay:
        plan_ids = set(list_spiritual_plans())
    result = []
    for pid in sorted(plan_ids):
        plan = load_spiritual_plan(pid)
        if plan:
            plan["id"] = pid
            result.append(plan)
    return result


def load_spiritual_plan_showcase_candidates(
    user_context: dict[str, Any] | None = None,
) -> list[dict[str, Any]]:
    """Return ranked shortlist of spiritual plans for Sage to present to user.

    Uses user_context (metrics, career profile, therapy insights) when available.
    For now returns all plans; future: LLM or heuristic ranking based on context.
    """
    plans = load_spiritual_plans_by_taxonomy()
    if user_context:
        pass  # Future: rank by metric alignment, career domain, therapy themes
    return plans[:5]
