from __future__ import annotations

import re
import shutil
from pathlib import Path


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


def pick_domain(stem: str) -> str:
    auth_names = {
        "admins",
        "auth_group",
        "auth_group_permissions",
        "auth_permission",
        "auth_user",
        "auth_user_groups",
        "auth_user_user_permissions",
        "model_has_permissions",
        "model_has_roles",
        "password_reset_tokens",
        "role_has_permissions",
        "roles",
        "permissions",
        "users",
    }
    django_core = {
        "django_admin_log",
        "django_content_type",
        "django_migrations",
        "django_session",
        "migrations",
        "sessions",
        "cache",
        "cache_locks",
        "failed_jobs",
        "job_batches",
        "jobs",
    }
    content = {
        "about",
        "about_structs",
        "about_values",
        "authors",
        "blog_categories",
        "blogs",
        "faqs",
        "menus",
        "pages",
        "sections",
        "sliders",
        "statistics",
        "testimonials",
        "teams",
        "before_afters",
        "benefits",
        "offers",
    }
    media = {
        "albums",
        "album_images",
        "galleries",
        "gallery_images",
        "gallery_videos",
        "brand_images",
        "category_images",
        "product_images",
        "project_images",
        "service_images",
    }
    catalog = {
        "attributes",
        "attribute_values",
        "brands",
        "categories",
        "plans",
        "plan_attributes",
        "plan_attribute_values",
        "products",
        "projects",
        "services",
        "partener_product",
        "parteners",
    }
    crm = {
        "career_applications",
        "clients",
        "contact_us",
        "emails",
        "finance_applications",
        "phones",
        "site_addresses",
        "subscribes",
        "working_hours",
    }
    seo_growth = {
        "redirects",
        "seo_assistants",
        "performance_metrics",
        "ai_generated_contents",
    }
    infra = {"domains", "hostings", "pwa_settings", "settings"}

    if stem in auth_names:
        return "authn"
    if stem in django_core:
        return "django_core"
    if stem in content:
        return "content"
    if stem in media:
        return "media"
    if stem in catalog:
        return "catalog"
    if stem in crm:
        return "crm"
    if stem in seo_growth:
        return "seo"
    if stem in infra:
        return "infra"
    return "misc"


def build_model_defs_init() -> None:
    import_lines: list[str] = []
    class_names: list[str] = []

    for file_path in sorted(MODEL_DEFS.rglob("*.py")):
        if file_path.name == "__init__.py":
            continue
        rel = file_path.relative_to(MODEL_DEFS).with_suffix("")
        module_path = ".".join(rel.parts)
        content = file_path.read_text(encoding="utf-8")
        match = CLASS_RE.search(content)
        if not match:
            continue
        class_name = match.group(1)
        import_lines.append(f"from .{module_path} import {class_name}")
        class_names.append(class_name)

    out = "\n".join(import_lines) + "\n\n"
    out += "__all__ = [\n"
    out += "".join(f'    "{name}",\n' for name in class_names)
    out += "]\n"
    (MODEL_DEFS / "__init__.py").write_text(out, encoding="utf-8")


def ensure_package_inits() -> None:
    for dir_path in sorted(p for p in MODEL_DEFS.iterdir() if p.is_dir()):
        init_file = dir_path / "__init__.py"
        if not init_file.exists():
            init_file.write_text("", encoding="utf-8")


def organize() -> None:
    model_files = [
        p
        for p in MODEL_DEFS.glob("*.py")
        if p.name != "__init__.py"
    ]

    for model_file in model_files:
        domain = pick_domain(model_file.stem)
        target_dir = MODEL_DEFS / domain
        target_dir.mkdir(exist_ok=True)
        shutil.move(str(model_file), str(target_dir / model_file.name))

    ensure_package_inits()
    build_model_defs_init()
    print(f"Organized {len(model_files)} model files into domain folders.")


if __name__ == "__main__":
    organize()
