"""
gdep.init_context
gdep init / gdep context 커맨드 구현.

- gdep init  <path>    : .gdep/AGENTS.md 생성 (AI Agent용 프로젝트 컨텍스트)
- gdep context <path>  : 현재 프로젝트 컨텍스트를 stdout으로 출력
"""
from __future__ import annotations

import json
from datetime import datetime
from pathlib import Path

from . import runner
from .detector import ProjectKind, detect

# ── AGENTS.md 템플릿 생성 ─────────────────────────────────────

def _build_agents_md(project_path: str) -> str:
    """
    프로젝트를 분석해서 AI Agent용 .gdep/AGENTS.md 내용을 생성한다.
    이 파일은 Claude / Cursor / Gemini 등이 프로젝트 루트에서 자동으로 읽어
    'gdep MCP를 어떻게, 언제 써야 하는가'를 이해하게 한다.
    """
    profile = detect(project_path)
    lines: list[str] = []

    # ── 헤더 ──────────────────────────────────────────────────
    lines += [
        "# gdep Agent Context",
        f"> Generated: {datetime.now().strftime('%Y-%m-%d')}  |  "
        f"Engine: {profile.display}  |  Project: {profile.name}",
        "",
        "## What is gdep?",
        "",
        "This project uses **gdep** — a game codebase analysis tool with an MCP server.",
        "gdep provides structural analysis of C++/C# source code and engine assets",
        "(Unity prefabs, UE5 blueprints, GAS, AnimBlueprint, BehaviorTree, StateTree).",
        "",
        "**When you are asked to help with this codebase, ALWAYS prefer gdep MCP tools**",
        "over reading files manually. gdep understands game engine patterns that",
        "raw file reading misses (prefab bindings, blueprint references, GAS tags, etc.).",
        "",
    ]

    # ── 프로젝트 기본 정보 ────────────────────────────────────
    src_path = str(profile.source_dirs[0]) if profile.source_dirs else str(profile.root)
    lines += [
        "## Project Info",
        "",
        "| Field | Value |",
        "|-------|-------|",
        f"| Engine | {profile.display} |",
        f"| Project Name | {profile.name} |",
        f"| Root | `{profile.root}` |",
        f"| Source Path | `{src_path}` |",
        "",
    ]

    # ── 빠른 스캔 결과 (클래스 수, 결합도 Top5) ───────────────
    try:
        scan_result = runner.scan(profile, circular=True, dead_code=True,
                                  deep=False, top=10, fmt="json")
        if scan_result.ok and scan_result.data:
            d = scan_result.data
            summary = d.get("summary", {})
            coupling = d.get("coupling", [])[:5]
            cycles = d.get("cycles", [])[:5]
            dead = d.get("deadNodes", [])[:5]

            lines += [
                "## Codebase Snapshot (auto-generated)",
                "",
                f"- Files: **{summary.get('fileCount', '?')}**",
                f"- Classes: **{summary.get('classCount', '?')}**",
                f"- Dead Code candidates: **{summary.get('deadCount', 0)}**",
                "",
            ]

            if coupling:
                lines += ["### High-Coupling Classes (most referenced)", ""]
                for item in coupling:
                    lines.append(f"- `{item['name']}` — score {item['score']}")
                lines.append("")

            if cycles:
                lines += ["### Circular Dependencies", ""]
                for c in cycles:
                    lines.append(f"- {c}")
                lines.append("")
    except Exception:
        pass  # 스캔 실패해도 나머지는 계속

    # ── 엔진별 추가 정보 ──────────────────────────────────────
    if profile.kind == ProjectKind.UNREAL:
        _append_ue5_context(lines, src_path)
    elif profile.kind == ProjectKind.UNITY:
        _append_unity_context(lines, src_path)

    # ── MCP 사용 가이드 ───────────────────────────────────────
    lines += _build_mcp_guide(profile, src_path)

    return "\n".join(lines)


def _append_ue5_context(lines: list[str], src_path: str) -> None:
    """UE5 전용 GAS / BT / StateTree 컨텍스트 추가."""
    try:
        from .ue5_gas_analyzer import analyze_gas
        gas = analyze_gas(src_path)
        # Summary 줄만 추출
        gas_lines = [l for l in gas.splitlines()
                     if l.startswith("- Abilities") or
                        l.startswith("- Effects") or
                        l.startswith("- AttributeSets") or
                        l.startswith("- GameplayTags")]
        if gas_lines:
            lines += ["## GAS (Gameplay Ability System) Summary", ""]
            lines += gas_lines
            lines.append("")
    except Exception:
        pass

    try:
        from .ue5_ai_analyzer import analyze_behavior_tree, analyze_state_tree
        st = analyze_state_tree(src_path)
        if "No StateTree" not in st:
            st_names = [l.strip("# ").strip()
                        for l in st.splitlines() if l.startswith("## ")]
            if st_names:
                lines += ["## StateTrees found", ""]
                for n in st_names:
                    lines.append(f"- `{n}`")
                lines.append("")

        bt = analyze_behavior_tree(src_path)
        if "No BehaviorTree" not in bt:
            bt_names = [l.strip("# ").strip()
                        for l in bt.splitlines() if l.startswith("## ")]
            if bt_names:
                lines += ["## BehaviorTrees found", ""]
                for n in bt_names:
                    lines.append(f"- `{n}`")
                lines.append("")
    except Exception:
        pass


def _append_unity_context(lines: list[str], src_path: str) -> None:
    """Unity 전용 Animator / Event 컨텍스트 추가."""
    try:
        from .unity_animator import _find_controllers
        controllers = _find_controllers(src_path)
        if controllers:
            lines += ["## Animator Controllers found", ""]
            for c in controllers[:10]:
                lines.append(f"- `{c.stem}` ({c.name})")
            lines.append("")
    except Exception:
        pass


def _build_mcp_guide(profile, src_path: str) -> list[str]:
    """엔진별 MCP 도구 사용 가이드 생성."""
    lines = [
        "## How to Use gdep MCP Tools",
        "",
        "**Default project_path for all tools:** `" + src_path + "`",
        "",
        "### Decision Guide: Which tool to use when?",
        "",
        "| Question | Tool to use |",
        "|----------|------------|",
        "| What classes exist / how are they coupled? | `execute_gdep_cli([\"scan\", path, \"--circular\"])` |",
        "| What does class X do? | `explore_class_semantics(path, \"ClassName\")` |",
        "| If I change class X, what breaks? | `analyze_impact_and_risk(path, \"ClassName\")` |",
        "| How does method X.Y work internally? | `trace_gameplay_flow(path, \"Class\", \"Method\")` |",
        "| Is the codebase healthy? Tech debt? | `inspect_architectural_health(path)` |",
        "| Raw CLI access (any command) | `execute_gdep_cli([\"command\", path, ...])` |",
    ]

    if profile.kind == ProjectKind.UNREAL:
        lines += [
            "| GAS abilities / effects / tags? | `analyze_ue5_gas(path)` |",
            "| AI behavior (BT / StateTree)? | `analyze_ue5_behavior_tree(path)` or `analyze_ue5_state_tree(path)` |",
            "| Animation states / montage notifies? | `analyze_ue5_animation(path)` |",
        ]
    elif profile.kind == ProjectKind.UNITY:
        lines += [
            "| Inspector event bindings? | `find_unity_event_bindings(path)` |",
            "| Animator state machine? | `analyze_unity_animator(path)` |",
        ]

    lines += [
        "",
        "### Recommended First Steps for This Project",
        "",
        "```",
        "# 1. Understand project structure",
        f'explore_class_semantics("{src_path}", "<MainClass>")',
        "",
        "# 2. Before modifying any class",
        f'analyze_impact_and_risk("{src_path}", "<ClassName>")',
        "",
        "# 3. Full health check",
        f'inspect_architectural_health("{src_path}")',
        "```",
        "",
        "### Important Notes",
        "",
        "- gdep works **offline** — no need to open the engine editor",
        "- Results are **stateless on-demand** — always reflects the latest saved files",
        "- Summaries are **cached** in `.gdep_cache/summaries/` to save API calls",
        "- Hint files (`.gdep-hints.json`) improve `flow` tracing for singleton patterns",
        "",
    ]
    return lines


# ── Context 출력 (stdout) ─────────────────────────────────────

def build_context_output(project_path: str) -> str:
    """
    gdep context 커맨드용 — AI에게 직접 붙여넣을 수 있는 컨텍스트 출력.
    .gdep/AGENTS.md가 있으면 그걸 읽고, 없으면 즉석 생성.
    """
    profile = detect(project_path)
    agents_md = Path(profile.root) / ".gdep" / "AGENTS.md"

    if agents_md.exists():
        return agents_md.read_text(encoding="utf-8")

    # 즉석 생성 (저장하지 않음)
    return _build_agents_md(project_path)
