"""FRREP-UR006 — role-agnostic "complete your professional profile" check.

The PRD asks every newly verified user (not just RIMS applicants — see
``apps.rims.grants.profile_gate`` for that narrower, eligibility-driven gate)
to be nudged toward filling in a professional profile covering academic
qualifications, professional background, areas of interest, country, and a
biography. This module is the single source of truth for what "complete"
means for that nudge so the post-verification message and the dashboard
banner can't drift apart.

Kept intentionally cheap: a single ``user.profile`` lookup (already resolved
via the reverse OneToOne descriptor, which ``getattr(..., None)`` handles
safely even when no ``UserProfile`` row exists yet — no writes, no N+1).
"""
from __future__ import annotations

# (label, get-value-from-profile) — order drives the reading order of the
# "missing" list shown in the banner / nudge message.
_REQUIRED_PROFILE_FIELDS = [
    ("country", lambda p: p.country),
    ("areas of interest", lambda p: p.areas_of_interest),
    ("biography", lambda p: p.bio),
    ("professional background", lambda p: p.professional_background),
    ("academic qualifications", lambda p: p.qualifications),
]


def profile_completion(user) -> dict:
    """Return completion state for ``user``.

    ``{"percent": int, "missing": [label, ...], "items": [{"label", "done"}, ...]}``.
    ``items`` carries every required field with its done/not-done flag so a
    progress checklist can render what's still outstanding; ``missing`` (the
    not-done subset, in reading order) is kept for the existing banner/nudge
    consumers.

    A user with no ``UserProfile`` row yet (never visited the profile page)
    is treated as 0% complete rather than raising.
    """
    if not getattr(user, "is_authenticated", False):
        items = [{"label": label, "done": False} for label, _ in _REQUIRED_PROFILE_FIELDS]
        return {
            "percent": 0,
            "missing": [it["label"] for it in items],
            "items": items,
        }

    profile = getattr(user, "profile", None)
    items = [
        {"label": label, "done": bool(profile and getter(profile))}
        for label, getter in _REQUIRED_PROFILE_FIELDS
    ]
    missing = [it["label"] for it in items if not it["done"]]
    total = len(items)
    met = total - len(missing)
    percent = round(met / total * 100) if total else 100
    return {"percent": percent, "missing": missing, "items": items}
