#!/usr/bin/env python3
from __future__ import annotations

import json
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def get_workspace_root() -> Path:
    """WORKSPACE_ROOT env var takes priority; fallback to scripts/../"""
    env_val = os.environ.get("WORKSPACE_ROOT")
    if env_val:
        return Path(env_val)
    return Path(__file__).parent.parent


def _champions_dir() -> Path:
    return get_workspace_root() / "memory" / "skill-learning" / "champions"


def _champions_archive_dir() -> Path:
    return get_workspace_root() / "memory" / "skill-learning" / "champions-archive"


def _learnings_path() -> Path:
    return get_workspace_root() / "memory" / "skill-learning" / "learnings.jsonl"


def _eval_axes_path() -> Path:
    return get_workspace_root() / "skills" / "shared" / "eval-axes.json"


def load_eval_axes(skill_name: str) -> list[str]:
    """Load eval axes for a skill from eval-axes.json. Returns [] if missing."""
    path = _eval_axes_path()
    if not path.exists():
        return []
    try:
        data: dict[str, Any] = json.loads(path.read_text(encoding="utf-8"))
        return data.get(skill_name, [])
    except (json.JSONDecodeError, OSError):
        return []


def load_champion(skill_name: str) -> dict[str, Any] | None:
    """Load champions/{skill_name}.json. Returns None if not found."""
    path = _champions_dir() / f"{skill_name}.json"
    if not path.exists():
        return None
    return json.loads(path.read_text(encoding="utf-8"))


def save_champion(skill_name: str, data: dict[str, Any]) -> Path:
    """Save data to champions/{skill_name}.json. Creates directories if needed."""
    champions_dir = _champions_dir()
    champions_dir.mkdir(parents=True, exist_ok=True)
    path = champions_dir / f"{skill_name}.json"
    path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
    return path


def archive_champion(skill_name: str) -> Path | None:
    """Move existing champion to champions-archive/{skill_name}/{timestamp}.json.
    Returns None if champion does not exist."""
    source = _champions_dir() / f"{skill_name}.json"
    if not source.exists():
        return None
    timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    archive_skill_dir = _champions_archive_dir() / skill_name
    archive_skill_dir.mkdir(parents=True, exist_ok=True)
    dest = archive_skill_dir / f"{timestamp}.json"
    source.rename(dest)
    return dest


def append_learning(entry: dict[str, Any]) -> None:
    """Append a JSON line to learnings.jsonl. Creates directories if needed."""
    path = _learnings_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(entry, ensure_ascii=False) + "\n")


def compare_outputs(
    output_a: str,
    output_b: str,
    eval_axes: list[str],
    skill_name: str,
) -> dict[str, Any]:
    """AI 비교 판정. ANTHROPIC_API_KEY가 없으면 길이 기반 fallback."""
    try:
        from output_review_ai import compare_outputs_ai

        return compare_outputs_ai(output_a, output_b, eval_axes, skill_name)
    except (ImportError, EnvironmentError):
        # Fallback: 길이 기반 비교 (API 키 없는 환경, 테스트 등)
        len_a, len_b = len(output_a), len(output_b)
        winner = "A" if len_a >= len_b else "B"
        return {
            "winner": winner,
            "reason": f"Fallback comparison for '{skill_name}': A len={len_a}, B len={len_b}",
            "scores": {},
        }


def load_skill_registry(skill_name: str) -> dict[str, Any] | None:
    """skill-registry.json에서 스킬 정보를 로드합니다."""
    registry_path = Path(os.environ.get("HOME", "")) / ".claude" / "skills" / "shared" / "skill-registry.json"
    if not registry_path.exists():
        return None
    try:
        data = json.loads(registry_path.read_text(encoding="utf-8"))
        return data.get(skill_name)
    except (json.JSONDecodeError, OSError):
        return None


def save_enhancement_learnings(skill_name: str, enhancement: dict[str, Any]) -> None:
    """enhancement에서 learnings를 learnings_archiver를 통해 저장합니다."""
    import sys

    for learning_text in enhancement.get("learnings", []):
        try:
            sys.path.insert(0, str(Path(__file__).parent))
            from learnings_archiver import add_learning as archiver_add

            archiver_add(skill_name=skill_name, source="champion-battle", learning=learning_text)
        except (ImportError, Exception):
            pass


def update_champion_status(champion: dict[str, Any]) -> dict[str, Any]:
    """Update status based on win/loss record. Priority order as per spec."""
    reinit = champion.get("reinit_count_this_month", 0)
    losses = champion.get("consecutive_losses", 0)
    defenses = champion.get("consecutive_defenses", 0)

    if reinit >= 2:
        champion["status"] = "manual_intervention_required"
    elif losses >= 3:
        champion["status"] = "unstable"
    elif defenses >= 5:
        champion["status"] = "stable"
    else:
        champion["status"] = "active"

    return champion


def build_champion_data(
    skill_name: str,
    skill_type: str,
    champion_output: str,
    eval_axes_used: list[str],
    init_method: str = "full_benchmark",
    benchmark_source: str = "online_expert",
) -> dict[str, Any]:
    """Build a champion.json schema-compliant dict."""
    now = datetime.now(timezone.utc).isoformat()

    # Next month's first day
    today = datetime.now(timezone.utc)
    if today.month == 12:
        next_month = today.replace(year=today.year + 1, month=1, day=1)
    else:
        next_month = today.replace(month=today.month + 1, day=1)
    month_reset_date = next_month.strftime("%Y-%m-%d")

    return {
        "skill_name": skill_name,
        "skill_type": skill_type,
        "champion_output": champion_output,
        "eval_axes_used": eval_axes_used,
        "created_at": now,
        "last_used": now,
        "status": "active",
        "consecutive_defenses": 0,
        "consecutive_losses": 0,
        "reinit_count_this_month": 0,
        "month_reset_date": month_reset_date,
        "init_method": init_method,
        "benchmark_source": benchmark_source,
    }


def record_defense(champion: dict[str, Any]) -> dict[str, Any]:
    """Record a defense: increment consecutive_defenses, reset consecutive_losses."""
    champion["consecutive_defenses"] = champion.get("consecutive_defenses", 0) + 1
    champion["consecutive_losses"] = 0
    return champion


def record_loss(champion: dict[str, Any]) -> dict[str, Any]:
    """Record a loss: increment consecutive_losses, reset consecutive_defenses."""
    champion["consecutive_losses"] = champion.get("consecutive_losses", 0) + 1
    champion["consecutive_defenses"] = 0
    return champion
