"""role_of — the app's ONE authority on a player's role.

M0 policy (plan-v1 §6.2): a player who is the boundary_player of any
team_node is a "lead"; everyone else (including a player with no team
yet) is a "player". Reported to the BW hub via bw_auth.report_role —
display-only there; the APP is the sole authority on what a role can do.

M6 extends THIS module (per-match roles, back-office bands, etc.) —
keep every role decision here so it changes in one place.
"""
from __future__ import annotations

from sqlalchemy import select
from sqlalchemy.orm import Session

from ..db import SessionLocal
from ..models import Player, TeamNode

#: App admins by BW username. The server owner drives builds and support;
#: this is deliberately a code-level constant, not a DB flag (M0).
ADMIN_USERNAMES = frozenset({"rian"})

ROLE_LEAD = "lead"
ROLE_PLAYER = "player"


def is_admin(username: str) -> bool:
    return (username or "").strip().lower() in ADMIN_USERNAMES


def role_of(username: str, db: Session | None = None) -> str:
    """"lead" if this username's player is a boundary player of any
    team_node, else "player" (also the default when the player row or any
    team structure doesn't exist yet — M0 ships teamless)."""
    owns = db is None
    if owns:
        db = SessionLocal()
    try:
        player_id = db.scalar(
            select(Player.id).where(Player.username == (username or "").strip())
        )
        if player_id is None:
            return ROLE_PLAYER
        leads = db.scalar(
            select(TeamNode.id)
            .where(TeamNode.boundary_player_id == player_id)
            .limit(1)
        )
        return ROLE_LEAD if leads is not None else ROLE_PLAYER
    finally:
        if owns:
            db.close()
