"""The ONE place that decides what a user may see. Every view goes through these."""
from django.utils import timezone

from .models import School

BASIC_COLUMNS = ["organizationCode", "districtName", "municipalityName", "ward",
                 "organizationType", "total_students"]
ALWAYS_COLUMNS = ["organizationId", "organizationName"]


def all_columns():
    first = School.objects.values_list("data", flat=True).first() or {}
    return list(first.keys())


def visible_schools(user):
    """Schools matching ANY of the user's active rules. No rules = nothing."""
    if user.is_superuser:
        return School.objects.all()
    qs_rules = [r for r in user.access_rules.all() if r.active]
    if not qs_rules:
        return School.objects.none()
    combined = None
    for rule in qs_rules:
        q = rule.to_q()
        if q is None:                      # a rule with no conditions shares everything
            return School.objects.all()
        combined = q if combined is None else (combined | q)
    return School.objects.filter(combined)


def allowed_columns(user):
    cols = all_columns()
    if user.is_superuser:
        return cols
    profile = getattr(user, "access_profile", None)
    chosen = (profile.visible_columns if profile and profile.visible_columns else BASIC_COLUMNS)
    keep = set(ALWAYS_COLUMNS) | set(chosen)
    return [c for c in cols if c in keep]


def can_export(user):
    if user.is_superuser:
        return True
    profile = getattr(user, "access_profile", None)
    return bool(profile and profile.can_export)


def crm_level(user):
    """'none' | 'view' | 'edit'"""
    if user.is_superuser:
        return "edit"
    profile = getattr(user, "access_profile", None)
    return profile.crm_access if profile else "none"


def crm_can_assign(user):
    if user.is_superuser:
        return True
    profile = getattr(user, "access_profile", None)
    return bool(profile and profile.crm_can_assign)


def shaped_rows(user):
    """The rows this user may see, cut down to the columns they may see
    (plus the CRM columns if they have CRM access)."""
    keep = set(allowed_columns(user))
    qs = visible_schools(user).order_by("district_id", "organization_id")
    if crm_level(user) == "none":
        return [{k: v for k, v in d.items() if k in keep} for d in qs.values_list("data", flat=True)]
    rows = []
    for d, st, pr, ow, lc, nf in qs.values_list(
            "data", "lead__stage", "lead__priority", "lead__owner__username",
            "lead__last_contacted_at", "lead__next_followup"):
        r = {k: v for k, v in d.items() if k in keep}
        r["crm_stage"] = st or "new"
        r["crm_priority"] = pr or ""
        r["crm_owner"] = ow
        r["crm_last_contacted"] = timezone.localtime(lc).date().isoformat() if lc else None
        r["crm_next_followup"] = nf.isoformat() if nf else None
        rows.append(r)
    return rows
