from __future__ import annotations

import re
from pathlib import Path


ROOT = Path(__file__).resolve().parent
MODEL_DEFS = ROOT / "legacydb" / "model_defs"
ADMIN_DEFS = ROOT / "legacydb" / "admin_defs"
CLASS_RE = re.compile(r"^class\s+([A-Za-z_][A-Za-z0-9_]*)\(models\.Model\):", re.M)


def discover_models():
    result: list[tuple[str, str, str]] = []
    for path in sorted(MODEL_DEFS.rglob("*.py")):
        if path.name == "__init__.py":
            continue
        text = path.read_text(encoding="utf-8")
        match = CLASS_RE.search(text)
        if not match:
            continue
        class_name = match.group(1)
        rel = path.relative_to(MODEL_DEFS).with_suffix("")
        parts = list(rel.parts)
        domain = parts[0] if len(parts) > 1 else "misc"
        stem = parts[-1]
        module_path = ".".join(parts)
        result.append((domain, stem, class_name + "|" + module_path))
    return result


def build():
    ADMIN_DEFS.mkdir(exist_ok=True)
    model_entries = discover_models()
    imports_for_root: list[str] = []

    for domain, stem, packed in model_entries:
        class_name, module_path = packed.split("|", 1)
        domain_dir = ADMIN_DEFS / domain
        domain_dir.mkdir(exist_ok=True)
        admin_file = domain_dir / f"{stem}_admin.py"

        admin_class = f"{class_name}Admin"
        body = (
            "from django.contrib import admin\n"
            "from django.core.exceptions import ImproperlyConfigured\n"
            f"from ...model_defs.{module_path} import {class_name}\n\n\n"
            f"class {admin_class}(admin.ModelAdmin):\n"
            "    pass\n\n\n"
            "try:\n"
            f"    admin.site.register({class_name}, {admin_class})\n"
            "except ImproperlyConfigured:\n"
            "    # Skip models Django admin cannot register (e.g. composite PK).\n"
            "    pass\n"
        )
        admin_file.write_text(body, encoding="utf-8")
        imports_for_root.append(f"from .{domain}.{stem}_admin import {admin_class}")

    # per-domain __init__.py
    for domain_dir in sorted(p for p in ADMIN_DEFS.iterdir() if p.is_dir()):
        lines: list[str] = []
        for file in sorted(domain_dir.glob("*_admin.py")):
            cls_name = "".join(part.capitalize() for part in file.stem.split("_"))
            lines.append(f"from .{file.stem} import {cls_name}")
        lines.append("")
        domain_dir.joinpath("__init__.py").write_text("\n".join(lines), encoding="utf-8")

    root_init = "\n".join(imports_for_root) + "\n"
    (ADMIN_DEFS / "__init__.py").write_text(root_init, encoding="utf-8")
    (ROOT / "legacydb" / "admin.py").write_text(
        "from .admin_defs import *  # noqa: F401,F403\n", encoding="utf-8"
    )

    print(f"Generated admin defs for {len(model_entries)} models.")


if __name__ == "__main__":
    build()
