"""
Architecture Context Generator — produces a human-readable ARCHITECTURE.md.

No API calls. No keys. Built entirely from the pre-built index.

Run once:   kodara context <path>
Keep fresh: kodara watch --context <path>
"""

from __future__ import annotations

from pathlib import Path

from ..memory.store import MemoryStore, KodaraIndex


def generate_context(repo_root: str) -> str:
    """
    Generate ARCHITECTURE.md from the pre-built index. No external calls.

    Returns: path to generated file.
    Raises:  ValueError if not indexed yet.
    """
    root = Path(repo_root).resolve()
    store = MemoryStore(root)
    idx = store.load()

    if not idx:
        raise ValueError(f"Not indexed. Run: kodara init {repo_root}")

    content = _render(idx)
    out_path = root / "ARCHITECTURE.md"
    out_path.write_text(content, encoding="utf-8")
    return str(out_path)


def _narrative(idx: KodaraIndex) -> str:
    langs = ", ".join(idx.language_counts.keys())
    top = _top_modules(idx, 5)
    mod_names = [m.get("module_name") or Path(m["path"]).stem for m in top]
    summaries = [m["summary"] for m in top if m.get("summary")]
    return (
        f"{idx.display_name} — {langs} project, {idx.file_count} files. "
        f"Core modules: {', '.join(mod_names)}. "
        + (" ".join(summaries[:2]) if summaries else "")
    ).strip()


# ── Renderer ──────────────────────────────────────────────────────────────────


def _render(idx: KodaraIndex) -> str:
    narrative = _narrative(idx)
    lines = [
        f"# {idx.display_name} — Architecture",
        f"",
        f"> Auto-generated by Codara. Regenerate: `kodara context`",
        f"",
        f"## Overview",
        f"",
        narrative,
        f"",
        f"## Key Modules",
        f"",
    ]

    for mod in _top_modules(idx, 10):
        path = mod.get("path", "")
        summary = mod.get("summary", "")
        fns = mod.get("functions", [])[:6]
        classes = mod.get("classes", [])[:3]
        git = mod.get("git", {})

        lines.append(f"### `{path}`")
        if summary:
            lines.append(summary)

        detail: list[str] = []
        if classes:
            detail.append(f"**Classes:** {', '.join(classes)}")
        if fns:
            detail.append(f"**Functions:** {', '.join(fns)}")
        if git.get("last_author"):
            detail.append(f"**Last change:** {git['last_author']} — {git.get('last_message', '')} ({git.get('last_date', '')})")
        if detail:
            lines.extend(detail)
        lines.append("")

    hubs = _find_hubs(idx)
    if hubs:
        lines += ["## Most-imported Modules", ""]
        for path, count in hubs[:5]:
            name = idx.modules.get(path, {}).get("module_name") or Path(path).stem
            lines.append(f"- `{name}` — used by {count} modules")
        lines.append("")

    # Contributors from git
    all_authors: dict[str, int] = {}
    for mod in idx.modules.values():
        for a in mod.get("git", {}).get("top_authors", []):
            all_authors[a["name"]] = all_authors.get(a["name"], 0) + a["commits"]
    if all_authors:
        lines += ["## Contributors", ""]
        for name, commits in sorted(all_authors.items(), key=lambda x: -x[1])[:5]:
            lines.append(f"- {name} ({commits} commits)")
        lines.append("")

    from datetime import datetime
    lines.append(f"---")
    lines.append(f"*Generated {datetime.now().strftime('%Y-%m-%d %H:%M')} · {idx.file_count} files indexed*")

    return "\n".join(lines)


# ── Helpers ───────────────────────────────────────────────────────────────────


def _top_modules(idx: KodaraIndex, limit: int) -> list[dict]:
    return sorted(
        idx.modules.values(),
        key=lambda m: len(m.get("functions", [])) + len(m.get("classes", [])) * 2,
        reverse=True,
    )[:limit]


def _find_hubs(idx: KodaraIndex) -> list[tuple[str, int]]:
    counts: dict[str, int] = {}
    for mod in idx.modules.values():
        for dep in mod.get("dependencies", []):
            counts[dep] = counts.get(dep, 0) + 1
    return sorted(counts.items(), key=lambda x: -x[1])
