#!/usr/bin/env python3
"""Generate CLI reference documentation from the Typer app.

Introspects the vodoo.main Typer application and generates Markdown pages
for each subcommand group under docs/cli/.

Usage:
    uv run python scripts/gen_cli_docs.py
"""

from __future__ import annotations

from pathlib import Path

import click
import typer.main

from vodoo.main import app

DOCS_DIR = Path(__file__).parent.parent / "docs" / "cli"

# Metadata for each subcommand group (description shown at top of page)
GROUP_META: dict[str, str] = {
    "helpdesk": "Manage Odoo Helpdesk tickets (requires Odoo Enterprise).",
    "project-task": "Manage Odoo Project Tasks.",
    "project": "Manage Odoo Projects (`project.project`).",
    "crm": "Manage Odoo CRM leads and opportunities.",
    "knowledge": "Manage Odoo Knowledge articles (requires Odoo Enterprise).",
    "timer": "Manage timers and timesheets.",
    "model": (
        "Generic CRUD operations for any Odoo model. "
        "Useful for ad-hoc queries and models not covered by the domain-specific commands."
    ),
    "security": (
        "Manage Vodoo API security groups and service accounts. "
        "See the full [Security Guide](../development/security.md) for architecture details."
    ),
}


def format_type(param: click.Parameter) -> str:
    """Format a Click parameter type for display."""
    type_name = param.type.name
    type_map = {
        "text": "TEXT",
        "integer": "INT",
        "float": "FLOAT",
        "boolean": "BOOL",
        "path": "PATH",
    }
    return type_map.get(type_name, type_name.upper())


def generate_command_doc(cmd: click.Command, cmd_name: str) -> str:
    """Generate Markdown documentation for a single command."""
    lines: list[str] = []
    lines.append(f"### {cmd_name}")
    lines.append("")

    # Help text
    if cmd.help:
        # Take the first paragraph as the summary
        help_text = cmd.help.strip()
        lines.append(help_text)
        lines.append("")

    # Arguments
    args = [p for p in cmd.params if isinstance(p, click.Argument)]
    options = [p for p in cmd.params if isinstance(p, click.Option) and p.name not in ("help",)]

    if args:
        lines.append("**Arguments:**")
        lines.append("")
        lines.append("| Argument | Type | Description |")
        lines.append("|----------|------|-------------|")
        for arg in args:
            required = "required" if arg.required else "optional"
            help_text = arg.help or required
            lines.append(f"| `{arg.name}` | {format_type(arg)} | {help_text} |")
        lines.append("")

    if options:
        lines.append("**Options:**")
        lines.append("")
        lines.append("| Option | Type | Description |")
        lines.append("|--------|------|-------------|")
        for opt in options:
            opt_str = " / ".join(f"`{o}`" for o in opt.opts)
            if opt.secondary_opts:
                opt_str += " / " + " / ".join(f"`{o}`" for o in opt.secondary_opts)
            help_text = opt.help or ""
            default = opt.default
            if default is not None and default not in ((), False):
                help_text += f" (default: {default})"
            lines.append(f"| {opt_str} | {format_type(opt)} | {help_text} |")
        lines.append("")

    return "\n".join(lines)


def generate_group_doc(group_name: str, group: click.Group, ctx: click.Context) -> str:
    """Generate full Markdown documentation for a subcommand group."""
    lines: list[str] = []

    lines.append(f"# vodoo {group_name}")
    lines.append("")

    # Group description
    meta = GROUP_META.get(group_name, group.help or "")
    lines.append(meta)
    lines.append("")

    # Auto-generation notice
    lines.append(
        "<!-- This file is auto-generated by scripts/gen_cli_docs.py. Do not edit manually. -->"
    )
    lines.append("")

    lines.append("## Commands")
    lines.append("")

    sub_ctx = click.Context(group, parent=ctx)
    for cmd_name in group.list_commands(sub_ctx):
        cmd = group.get_command(sub_ctx, cmd_name)
        if cmd is not None:
            lines.append(generate_command_doc(cmd, cmd_name))

    return "\n".join(lines)


def generate_index(groups: list[tuple[str, click.Group, str]]) -> str:
    """Generate the CLI index page."""
    lines: list[str] = []

    lines.append("# CLI Reference")
    lines.append("")
    lines.append(
        "<!-- This file is auto-generated by scripts/gen_cli_docs.py. Do not edit manually. -->"
    )
    lines.append("")
    lines.append("Vodoo provides a Typer-based CLI with the following subcommands:")
    lines.append("")
    lines.append("| Command | Description |")
    lines.append("|---------|-------------|")
    for name, group, _ in groups:
        help_text = group.help or ""
        lines.append(f"| [`{name}`]({name}.md) | {help_text} |")
    lines.append("")

    lines.append("## Global Options")
    lines.append("")
    lines.append("```")
    lines.append("vodoo --help")
    lines.append("vodoo <command> --help")
    lines.append("```")
    lines.append("")

    lines.append("## Output Modes")
    lines.append("")
    lines.append(
        "By default, Vodoo uses Rich tables for colorful terminal output. "
        "Use `--simple` on list commands for plain TSV output suitable for piping:"
    )
    lines.append("")
    lines.append("```bash")
    lines.append("vodoo helpdesk list --simple | cut -f1,2")
    lines.append("```")
    lines.append("")

    lines.append("## Common Patterns")
    lines.append("")
    lines.append(
        "All domain subcommands (`helpdesk`, `project-task`, `project`, `crm`) "
        "share a consistent interface:"
    )
    lines.append("")
    lines.append("| Action | Command |")
    lines.append("|--------|---------|")
    lines.append("| List records | `vodoo <cmd> list [--stage ...] [--search ...] [--limit N]` |")
    lines.append("| Show details | `vodoo <cmd> show <ID>` |")
    lines.append('| Add comment | `vodoo <cmd> comment <ID> "message"` |')
    lines.append('| Add note | `vodoo <cmd> note <ID> "message"` |')
    lines.append("| Update fields | `vodoo <cmd> set <ID> field=value ...` |")
    lines.append("| List fields | `vodoo <cmd> fields` |")
    lines.append("| List tags | `vodoo <cmd> tags` |")
    lines.append("| Add tag | `vodoo <cmd> tag <ID> <TAG_ID>` |")
    lines.append("| Message history | `vodoo <cmd> chatter <ID>` |")
    lines.append("| List attachments | `vodoo <cmd> attachments <ID>` |")
    lines.append("| Upload file | `vodoo <cmd> attach <ID> <FILE>` |")
    lines.append("| Download one | `vodoo <cmd> download <ATTACHMENT_ID>` |")
    lines.append("| Download all | `vodoo <cmd> download-all <ID>` |")
    lines.append("| Get URL | `vodoo <cmd> url <ID>` |")
    lines.append("")

    return "\n".join(lines)


def main() -> None:
    click_app = typer.main.get_command(app)
    ctx = click.Context(click_app)

    groups: list[tuple[str, click.Group, str]] = []

    for group_name in click_app.list_commands(ctx):
        group = click_app.get_command(ctx, group_name)
        if not isinstance(group, click.Group):
            continue

        # Generate per-group page
        content = generate_group_doc(group_name, group, ctx)
        out_path = DOCS_DIR / f"{group_name}.md"
        out_path.write_text(content + "\n", encoding="utf-8")
        print(f"  Generated {out_path}")
        groups.append((group_name, group, content))

    # Generate index
    index_content = generate_index(groups)
    index_path = DOCS_DIR / "index.md"
    index_path.write_text(index_content + "\n", encoding="utf-8")
    print(f"  Generated {index_path}")

    print(f"\n✓ Generated {len(groups) + 1} CLI reference pages")


if __name__ == "__main__":
    main()
