"""Auto-register every concrete model in ``INSTALLED_APPS`` with the admin.

Apps may still ship their own ``admin.py`` for hand-tuned ``ModelAdmin``
classes (which Django registers via ``admin.autodiscover``). This helper only
fills in the gaps for models that have no admin yet, so the operator never has
to write boilerplate just to see a model in the Django admin.

Every auto-registered model uses ``unfold.admin.ModelAdmin`` so it inherits
the Unfold styling, search, filter, and inline machinery.
"""

from __future__ import annotations

from django.apps import apps as django_apps
from django.contrib import admin
from django.contrib.admin.sites import AlreadyRegistered

try:
    from unfold.admin import ModelAdmin as UnfoldModelAdmin
except ImportError:  # pragma: no cover — unfold is a hard dep, but keep safe.
    UnfoldModelAdmin = admin.ModelAdmin  # type: ignore[assignment]


def _make_auto_admin(model) -> type[admin.ModelAdmin]:
    """Build a sane default ``ModelAdmin`` for an arbitrary model.

    Picks short text-ish fields for ``list_display``/``search_fields`` and
    common scoping fields for ``list_filter`` when present.
    """
    field_names: list[str] = []
    search_fields: list[str] = []
    list_filter: list[str] = []
    date_hierarchy: str | None = None

    for field in model._meta.get_fields():
        if not getattr(field, "concrete", False) or getattr(field, "many_to_many", False):
            continue
        name = field.name
        internal = field.get_internal_type()
        if internal in {"CharField", "SlugField", "EmailField", "UUIDField"}:
            if len(field_names) < 4:
                field_names.append(name)
            if internal in {"CharField", "SlugField", "EmailField"}:
                search_fields.append(name)
        elif internal in {"BooleanField",}:
            list_filter.append(name)
        elif internal in {"DateTimeField", "DateField"}:
            if date_hierarchy is None and name in {"created_at", "created", "updated_at"}:
                date_hierarchy = name
            list_filter.append(name)
        elif internal == "ForeignKey" and name in {"tenant", "organization_node", "workspace"}:
            list_filter.append(name)

    if not field_names:
        # Fallback so the changelist isn't empty.
        field_names = ["__str__"]

    attrs: dict[str, object] = {
        "list_display": tuple(field_names[:5]),
        "list_per_page": 50,
    }
    if search_fields:
        attrs["search_fields"] = tuple(search_fields[:6])
    if list_filter:
        attrs["list_filter"] = tuple(list_filter[:6])
    if date_hierarchy:
        attrs["date_hierarchy"] = date_hierarchy

    return type(f"{model.__name__}AutoAdmin", (UnfoldModelAdmin,), attrs)


def autoregister_all() -> int:
    """Register every concrete model not yet present in ``admin.site``.

    Returns the number of newly registered models (handy for logging/tests).
    """
    registered = 0
    for model in django_apps.get_models():
        if model._meta.abstract or model._meta.proxy:
            continue
        if admin.site.is_registered(model):
            continue
        try:
            admin.site.register(model, _make_auto_admin(model))
        except AlreadyRegistered:
            continue
        registered += 1
    return registered


__all__ = ["autoregister_all"]
