"""Configuration discovery, never a replacement for destination authorization."""
from django.contrib import admin
from django.urls import reverse
from apps.operations import queries

# The capability questions this module asks, as (permission, company_only).
# Declared once so the shared navigation shell can resolve them in one
# authoritative bulk call and so the shell and this module cannot drift apart.
CONFIGURATION_CAPABILITIES = {
    "sla.manage_slapolicy": True,
    "communications.manage_templates": True,
    "frontdesk.manage_slots": False,
    "inventory.manage_inventory": False,
    "inventory.view_stock": False,
}


def configuration_links():
    """The configuration link the shell already shows, as (title, url, permission, company_only).

    Built on demand: reverse() must not run while this module is being imported.
    """
    return ("Configuration", [
        ("SLA policies", reverse("sla:policies"), "sla.manage_slapolicy", True)])


def system_administrator(user):
    return bool(user.is_authenticated and user.is_active and user.is_staff and user.is_superuser)


def visible(request, can=None):
    user = request.user
    if not user.is_authenticated or not user.is_active:
        return False
    if can is None:
        def can(permission, company_only=False):
            return queries.capable(user, permission, company_only=company_only)
    return (system_administrator(user)
            or can("sla.manage_slapolicy", True)
            or can("communications.manage_templates", True)
            or can("frontdesk.manage_slots")
            # has_perm() last: it costs two queries on a cold user; the other terms are cheaper.
            or (user.is_staff and can("inventory.manage_inventory") and can("inventory.view_stock")
                and user.has_perm("inventory.change_inventorylocation")))


ADMIN_GROUPS = {
    "Organization": [("Companies", "organization", "company"), ("Regions", "organization", "region"),
                     ("Service centers", "organization", "servicecenter"), ("Departments", "organization", "department")],
    "People & Access": [("Users", "accounts", "user"), ("Organizational assignments", "organization", "userorganizationassignment"),
                         ("Roles and permission membership", "access", "role"), ("Role assignments", "access", "userroleassignment")],
    "Service Master Data: Product Catalog": [("Brands", "catalog", "brand"), ("Product categories", "catalog", "productcategory"),
                        ("Models", "catalog", "productmodel"), ("Variants", "catalog", "productvariant"),
                        ("Device identification policies", "catalog", "deviceidentificationpolicy")],
    "Service Master Data: Taxonomy": [("Service categories", "service_catalog", "servicecategory"),
        ("Complaint symptoms and applicability", "service_catalog", "complaintsymptom"),
        ("Fault diagnoses and applicability", "service_catalog", "faultdiagnosis"),
        ("Root causes and applicability (optional)", "service_catalog", "rootcause"),
        ("Repair actions and applicability", "service_catalog", "repairaction")],
    "Service Master Data: Parts": [("Part categories", "parts", "partcategory"), ("Spare parts and compatibility", "parts", "sparepart")],
}


ADMIN_NOTES = {
    "People & Access": "Advanced Django Admin: global users, multi-scope assignments and role permission membership. Primary assignments and lifecycle rules remain authoritative; native permissions do not create business scope.",
    "Organization": "Advanced Django Admin: Company > Region > Service Center; Departments belong to a company. Inspect parent and active state before changes. Deactivation uses lifecycle services; reactivation does not reopen children.",
    "Service Master Data: Product Catalog": "Advanced Django Admin: inspect brand, Product Category, model, variant and identification policy dependencies before editing. Existing validation and protective references remain in force.",
    "Service Master Data: Taxonomy": "Advanced Django Admin: ComplaintSymptom is the complaint dimension. Product Category applicability is not Complaint-to-ServiceCategory classification. RootCause may remain unknown/unconfirmed without a fabricated master record.",
    "Service Master Data: Parts": "Advanced Django Admin: model-wide and variant-specific compatibility remain distinct. Serialization policy locks after serialized units or posted inventory history.",
}

def sections(request, can=None):
    from django.apps import apps
    user, result = request.user, []
    if can is None:
        capabilities = queries.capability_map(user, CONFIGURATION_CAPABILITIES)
        can = lambda permission, company_only=False: capabilities.get((permission, company_only), False)
    if system_administrator(user):
        for label, entries in ADMIN_GROUPS.items():
            links = []
            for title, app, model_name in entries:
                model = apps.get_model(app, model_name)
                registered = admin.site._registry.get(model)
                if registered and registered.has_view_permission(request):
                    links.append((title, reverse(f"admin:{app}_{model_name}_changelist")))
            if links:
                result.append({"label": label, "links": links, "note": ADMIN_NOTES[label]})
    links = []
    for permission, label, route, company_only in [
        ("frontdesk.manage_slots", "Appointment slots and capacity", "configuration:slots", False),
        ("communications.manage_templates", "Notification templates", "communications:templates", True),
        ("sla.manage_slapolicy", "SLA policies", "sla:policies", True),
    ]:
        if can(permission, company_only):
            links.append((label, reverse(route)))
    if links:
        result.append({"label": "Operations", "links": links, "note": "Dated slots use center scope and existing capacity validation. SLA policies and templates use company scope. Policy edits do not rewrite ServiceCase SLA snapshots; template edits do not rewrite rendered notifications."})
    if user.is_staff and can("inventory.manage_inventory") and can("inventory.view_stock") and user.has_perm("inventory.change_inventorylocation"):
        result.append({"label": "Inventory", "links": [("Inventory locations",reverse("admin:inventory_inventorylocation_changelist"))],
                       "note": "Existing scoped Admin configuration. Ledgers and balances are not manually editable."})
    if system_administrator(user):
        result.append({"label": "System", "links": [("Readiness checks",reverse("configuration:readiness"))],
                       "note": "Read-only minimum-intake readiness, recommendations and optional features."})
    return result
