from __future__ import annotations

import ast
from pathlib import Path
from typing import Any


def python_outline(path: str) -> dict[str, Any]:
    p = Path(path)
    if not p.is_file():
        return {"ok": False, "error": "not a file"}
    try:
        tree = ast.parse(p.read_text(encoding="utf-8"), filename=str(p))
    except SyntaxError as e:
        return {"ok": False, "error": str(e)}
    items: list[dict[str, Any]] = []
    for node in tree.body:
        if isinstance(node, ast.FunctionDef | ast.AsyncFunctionDef):
            items.append(
                {
                    "kind": "function",
                    "name": node.name,
                    "lineno": node.lineno,
                    "async": isinstance(node, ast.AsyncFunctionDef),
                }
            )
        elif isinstance(node, ast.ClassDef):
            items.append({"kind": "class", "name": node.name, "lineno": node.lineno})
        elif isinstance(node, ast.Import):
            for n in node.names:
                items.append({"kind": "import", "name": n.name})
        elif isinstance(node, ast.ImportFrom):
            mod = node.module or ""
            for n in node.names:
                items.append({"kind": "from", "module": mod, "name": n.name})
    return {"ok": True, "path": str(p), "items": items}


def graph_json_format(
    nodes: list[dict[str, Any]], edges: list[dict[str, Any]]
) -> dict[str, Any]:
    return {
        "ok": True,
        "format": "graph_json",
        "data": {"nodes": nodes, "edges": edges},
    }


def mermaid_block(title: str | None, body: str) -> dict[str, Any]:
    t = title or "diagram"
    md = f"```mermaid\n{body.strip()}\n```"
    return {"ok": True, "title": t, "markdown": md}
