from __future__ import annotations

import json
from collections import defaultdict
from datetime import UTC, datetime
from pathlib import Path

from app.main import create_app

SERVER_DIR = Path(__file__).resolve().parents[1]
ROOT_DIR = SERVER_DIR.parent
OUTPUT_DIR = ROOT_DIR / "document" / "development" / "backend_api"
OPENAPI_PATH = OUTPUT_DIR / "openapi.json"
INVENTORY_PATH = OUTPUT_DIR / "interface_inventory.md"


def build_inventory(schema: dict[str, object]) -> str:
    paths = schema.get("paths", {})
    tag_groups: dict[str, list[tuple[str, str, str]]] = defaultdict(list)

    for path, operations in sorted(paths.items()):
        if not isinstance(operations, dict):
            continue
        for method, operation in sorted(operations.items()):
            if not isinstance(operation, dict):
                continue
            summary = str(operation.get("summary") or operation.get("operationId") or "-")
            tags = operation.get("tags") or ["untagged"]
            primary_tag = str(tags[0])
            tag_groups[primary_tag].append((method.upper(), str(path), summary))

    generated_at = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S UTC")
    lines = [
        "# Backend API Interface Inventory",
        "",
        f"- Generated at: `{generated_at}`",
        f"- API title: `{schema['info']['title']}`",
        f"- API version: `{schema['info']['version']}`",
        f"- Total paths: `{len(paths)}`",
        "",
        "## Tag Overview",
        "",
    ]

    for tag_name in sorted(tag_groups):
        lines.append(f"### {tag_name}")
        lines.append("")
        lines.append("| Method | Path | Summary |")
        lines.append("| --- | --- | --- |")
        for method, path, summary in tag_groups[tag_name]:
            lines.append(f"| `{method}` | `{path}` | {summary} |")
        lines.append("")

    return "\n".join(lines).strip() + "\n"


def main() -> None:
    app = create_app()
    schema = app.openapi()

    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    OPENAPI_PATH.write_text(
        json.dumps(schema, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    INVENTORY_PATH.write_text(build_inventory(schema), encoding="utf-8")

    print(f"OpenAPI exported to: {OPENAPI_PATH}")
    print(f"Interface inventory exported to: {INVENTORY_PATH}")


if __name__ == "__main__":
    main()
