"""
stage_map.py
────────────
Single source of truth for mapping the raw `round` integer that
appears in fraud_log.json to a human-readable interview stage name.

The main People Hub already defines its own stage table inside
`config.py` (STAGE_ASSESSMENT, STAGE_ROLEPLAY, …) — we mirror that
here on purpose so this module stays import-independent of the
parent app. Add new rounds in ONE place: this dict.
"""
from __future__ import annotations
from typing import Dict, Tuple


# (round_id) → (short_label, full_name, category, accent_color)
#
# Accent color is the badge color in the UI. Categories are used so
# the frontend can group rounds (technical / managerial / hr / etc.)
# in summary widgets without re-deriving the bucketing on the client.
_STAGE_TABLE: Dict[int, Tuple[str, str, str, str]] = {
    0: ("Pre-Session",      "Current Stage After Login",         "lobby",       "#94a3b8"),
    1: ("Round 1",          "Round 1 — AI Screening Assessment", "assessment",  "#3b82f6"),
    2: ("Round 2",          "Round 2 — Role Play",               "roleplay",    "#a855f7"),
    3: ("Round 3",          "Round 3 — Coding Test",             "coding",      "#0ea5e9"),
    4: ("Technical",        "Technical Round",                   "technical",   "#14b8a6"),
    5: ("Manager",          "Manager Round",                     "managerial",  "#f59e0b"),
    6: ("HR Round",         "HR Round",                          "hr",          "#ec4899"),
    7: ("Final Manager",    "Final Manager Round",               "managerial",  "#f97316"),
    8: ("Leadership",       "Leadership Round",                  "managerial",  "#ef4444"),
    9: ("Closing",          "Offer / Closing Round",             "closing",     "#10b981"),
}


# Canonical ordered list of rounds the UI should render as a stepper.
# Anything in fraud_log.json that doesn't map here falls under
# "Other / Extended" and is appended dynamically by the frontend.
CANONICAL_ROUND_ORDER = [0, 1, 2, 3, 4, 5, 6]


def describe_round(round_id: int) -> dict:
    """Return a rich descriptor for a raw round id.

    Always returns a usable dict — unknown ids get a labelled fallback
    so the UI never has to special-case missing data.
    """
    if round_id in _STAGE_TABLE:
        short, full, cat, color = _STAGE_TABLE[round_id]
        return {
            "round_id":    round_id,
            "short_label": short,
            "full_name":   full,
            "category":    cat,
            "accent":      color,
            "known":       True,
        }
    return {
        "round_id":    round_id,
        "short_label": f"Round {round_id}",
        "full_name":   f"Extended Round {round_id}",
        "category":    "extended",
        "accent":      "#64748b",
        "known":       False,
    }


def canonical_stage_track() -> list[dict]:
    """All canonical rounds in order — feeds the stepper at the top of
    the report. The frontend marks each one as 'flagged' if any event
    for that round arrived, otherwise 'clean'."""
    return [describe_round(r) for r in CANONICAL_ROUND_ORDER]


# ── Page-URL → round mapping ────────────────────────────────────────
#
# fraud_log.json events sometimes only carry a `metadata.page` (the
# raw browser path the event fired on) instead of a useful integer
# `round`. Management dashboards must NEVER display those raw paths —
# we map them to canonical round ids here. Substring-match keeps it
# robust against minor URL changes ("/people_hub_role_play?x=1",
# "/static/html/people_hub_role_play.html", etc.).
#
# Add new pages by appending a tuple — most-specific first so
# /people_hub_coding_assessment.html doesn't accidentally match the
# /people_hub_assessment.html prefix.
_PAGE_PATTERNS: list[tuple[str, int]] = [
    ("people_hub_coding_assessment", 3),  # Round 3 — Coding
    ("people_hub_role_play",         2),  # Round 2 — Role Play
    ("people_hub_assessment",        1),  # Round 1 — AI Screening
    ("people_hub_setup",             0),  # Pre-session (setup screen)
    ("people_hub_login",             0),  # Pre-session (login screen)
    ("people_hub_profile",           0),  # Pre-session
]


def round_from_page(page: str | None) -> int | None:
    """Best-effort: derive a canonical round id from a page URL.

    Returns None when no pattern matches so callers can fall back to
    the event's own `round` field instead of forcing 0.
    """
    if not page:
        return None
    p = str(page).lower()
    for pat, rid in _PAGE_PATTERNS:
        if pat in p:
            return rid
    return None


def round_label_for_page(page: str | None) -> str | None:
    """Friendly label for a raw page URL — used by the frontend
    whenever it would otherwise show a path like
    `/people_hub_role_play`.

    Returns None when the URL isn't recognised so the caller can
    decide whether to hide the field entirely.
    """
    rid = round_from_page(page)
    if rid is None:
        return None
    return describe_round(rid)["full_name"]
