"""SubmitStream's View-As policy on top of the standard bw_view_as drop-in.

The drop-in owns the mechanism + guards (read-only default, no-escalation, server-
side authz); this module supplies the two app hooks and the glue. Targets are keyed
on the SubmitStream account id (as a string) so a client can be previewed even before
their first BW login. Hub oversight is reported with BW usernames/emails for display.

Policy (per owner decision):
  * admin   → may view as ANY non-admin user.
  * manager → may view as a CLIENT who shares a form the manager can access
              (a form the manager created or was granted).
  * read-only always (mode='readonly'); no 'act' mode is offered.
"""

from __future__ import annotations

from typing import Optional

import bw_view_as
from db import query, query_one

_RANK = {"admin": 100, "manager": 50, "client": 10}


def _client(cid: str):
    if not str(cid).isdigit():
        return None
    return query_one("SELECT * FROM clients WHERE id = ?", (int(cid),))


def rank_of(cid: str) -> int:
    row = _client(cid)
    return _RANK.get(row["role"], 0) if row else 0


def can_view_as(real_cid: str, target_cid: str) -> bool:
    """Server-side authority, re-checked on every start() AND on cookie resolution."""
    real, target = _client(real_cid), _client(target_cid)
    if not real or not target or target["role"] == "admin":
        return False
    if real["role"] == "admin":
        return True
    if real["role"] == "manager" and target["role"] == "client":
        # target must be granted a form the manager created or was granted
        row = query_one(
            "SELECT 1 FROM form_access fa JOIN forms f ON f.id = fa.form_id "
            "WHERE fa.client_id = ? AND (f.created_by = ? OR f.id IN "
            "(SELECT form_id FROM form_access WHERE client_id = ?)) LIMIT 1",
            (target["id"], real["id"], real["id"]))
        return row is not None
    return False


def viewable_targets(real_cid: str) -> list[dict]:
    """Who to offer in the picker — kept consistent with can_view_as."""
    real = _client(real_cid)
    if not real:
        return []
    if real["role"] == "admin":
        rows = query("SELECT id, name, email FROM clients WHERE role != 'admin' ORDER BY name")
    elif real["role"] == "manager":
        rows = query(
            "SELECT DISTINCT c.id, c.name, c.email FROM clients c "
            "JOIN form_access fat ON fat.client_id = c.id "
            "JOIN forms f ON f.id = fat.form_id "
            "WHERE c.role = 'client' AND (f.created_by = ? OR f.id IN "
            "(SELECT form_id FROM form_access WHERE client_id = ?)) ORDER BY c.name",
            (real["id"], real["id"]))
    else:
        return []
    return [{"username": str(r["id"]), "label": (r["name"] or r["email"] or f"user {r['id']}")}
            for r in rows]


def can_use(real_role: str) -> bool:
    return real_role in ("admin", "manager")


# ---- session-dict adapter over SubmitStream's signed cookie persistence ----

def build_session(real_client_id: int, acting_target: Optional[str]) -> dict:
    """A bw_view_as-compatible mutable session dict for one request."""
    sess: dict = {"user": str(real_client_id)}
    if acting_target:
        sess[bw_view_as.ACTING_KEY] = str(acting_target)
        sess[bw_view_as.MODE_KEY] = "readonly"
    return sess


def report_label(cid: str) -> str:
    """Display string for the hub — prefer the BW username, else email/name."""
    row = _client(cid)
    if not row:
        return str(cid)
    return row["bw_username"] or row["email"] or (row["name"] or f"user {cid}")
