#!/usr/bin/env python3
"""Generate skill and command catalog artifacts for fast navigation."""

from __future__ import annotations

import glob
import os
from collections import defaultdict
from pathlib import Path

import yaml

PROJECT_ROOT = Path(__file__).resolve().parents[1]
CATALOG_DIR = PROJECT_ROOT / "catalog"
SKILLS_GLOB = PROJECT_ROOT / "skills" / "*" / "SKILL.md"
COMMANDS_GLOB = PROJECT_ROOT / "commands" / "*.md"

SKILL_OPTIONAL_FIELDS = [
    "intent",
    "domain",
    "job",
    "stage",
    "time_to_value",
    "outputs",
    "related_skills",
    "aliases",
]


def read_frontmatter(path: Path) -> tuple[dict, str]:
    text = path.read_text(encoding="utf-8")
    if not text.startswith("---\n"):
        return {}, text
    parts = text.split("---", 2)
    if len(parts) < 3:
        return {}, text
    data = yaml.safe_load(parts[1]) or {}
    body = parts[2]
    return data, body


def load_skills() -> list[dict]:
    skills: list[dict] = []
    for raw_path in sorted(glob.glob(str(SKILLS_GLOB))):
        path = Path(raw_path)
        data, _ = read_frontmatter(path)
        if not data:
            continue

        item = {
            "name": data.get("name", ""),
            "description": data.get("description", ""),
            "type": data.get("type", ""),
            "path": str(path.relative_to(PROJECT_ROOT)),
        }
        for key in SKILL_OPTIONAL_FIELDS:
            if key in data:
                item[key] = data[key]
        skills.append(item)

    skills.sort(key=lambda x: x["name"])
    return skills


def load_commands() -> list[dict]:
    commands: list[dict] = []
    for raw_path in sorted(glob.glob(str(COMMANDS_GLOB))):
        path = Path(raw_path)
        data, _ = read_frontmatter(path)
        if not data:
            continue

        item = {
            "name": data.get("name", path.stem),
            "description": data.get("description", ""),
            "argument_hint": data.get("argument-hint", ""),
            "uses": data.get("uses", []),
            "outputs": data.get("outputs", []),
            "path": str(path.relative_to(PROJECT_ROOT)),
        }
        commands.append(item)

    commands.sort(key=lambda x: x["name"])
    return commands


def write_yaml(path: Path, payload: dict) -> None:
    path.write_text(yaml.safe_dump(payload, sort_keys=False, allow_unicode=False), encoding="utf-8")


def write_skills_by_type_markdown(path: Path, skills: list[dict]) -> None:
    grouped: dict[str, list[dict]] = defaultdict(list)
    for skill in skills:
        grouped[skill.get("type", "unknown")].append(skill)

    lines: list[str] = []
    lines.append("# Skills By Type")
    lines.append("")
    lines.append("Generated by `scripts/generate-catalog.py`. Do not edit manually.")
    lines.append("")

    for skill_type in ["component", "interactive", "workflow"]:
        items = grouped.get(skill_type, [])
        lines.append(f"## {skill_type.title()} ({len(items)})")
        lines.append("")
        for item in items:
            lines.append(f"- `{item['name']}` - {item['description']}")
            lines.append(f"  - `{item['path']}`")
        lines.append("")

    path.write_text("\n".join(lines).strip() + "\n", encoding="utf-8")


def write_commands_markdown(path: Path, commands: list[dict]) -> None:
    lines: list[str] = []
    lines.append("# Commands Catalog")
    lines.append("")
    lines.append("Generated by `scripts/generate-catalog.py`. Do not edit manually.")
    lines.append("")

    for command in commands:
        lines.append(f"## /{command['name']}")
        lines.append("")
        lines.append(f"- Description: {command['description']}")
        lines.append(f"- Argument hint: `{command['argument_hint']}`")
        lines.append(f"- Path: `{command['path']}`")
        uses = command.get("uses", [])
        outputs = command.get("outputs", [])
        lines.append("- Uses:")
        for skill_name in uses:
            lines.append(f"  - `{skill_name}`")
        lines.append("- Outputs:")
        for output in outputs:
            lines.append(f"  - {output}")
        lines.append("")

    path.write_text("\n".join(lines).strip() + "\n", encoding="utf-8")


def main() -> int:
    CATALOG_DIR.mkdir(parents=True, exist_ok=True)

    skills = load_skills()
    commands = load_commands()

    write_yaml(
        CATALOG_DIR / "skills-index.yaml",
        {
            "generated_from": "skills/*/SKILL.md",
            "count": len(skills),
            "skills": skills,
        },
    )
    write_yaml(
        CATALOG_DIR / "commands-index.yaml",
        {
            "generated_from": "commands/*.md",
            "count": len(commands),
            "commands": commands,
        },
    )

    write_skills_by_type_markdown(CATALOG_DIR / "skills-by-type.md", skills)
    write_commands_markdown(CATALOG_DIR / "commands.md", commands)

    print(f"Generated catalog for {len(skills)} skills and {len(commands)} commands.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
