// principal.jsx — Ryoko · Active-principal switcher
//
// Multi-principal household model: Mr A is the founder; Mrs A is co-principal;
// Bea + Henry are trial-tier adult children with scope-limited views. This
// module holds the active principal id, persists across pages, and exposes
// a predicate other surfaces use to filter content (NDA scope).
//
// Exposes:
//   window.RyokoPrincipal.list()                    — array of principal records
//   window.RyokoPrincipal.current()                 — active principal id (string)
//   window.RyokoPrincipal.currentRecord()           — full record
//   window.RyokoPrincipal.set(id)                   — switch
//   window.RyokoPrincipal.subscribe(fn)             — listener (returns unsubscribe)
//   window.RyokoPrincipal.canViewDoc(doc)           — vault scope predicate
//   window.RyokoPrincipal.canViewTrip(trip)         — trip scope predicate
//   window.RyokoPrincipal.isFounder()               — Mr A or Mrs A?
//
// State persists via sessionStorage key `rk.principal.active`.
// On any non-default principal, a "Viewing as …" pill mounts under the topbar.

(function () {
  const { useState, useEffect } = React;
  const KEY = "rk.principal.active";
  const DEFAULT = "ea";

  // Inline registry · mirrors household/data.jsx PRINCIPALS.
  // Only the fields needed for switching + scope predicates.
  const PRINCIPALS = [
    {
      id: "ea",
      name: "Mr. Edmund Aldercott",
      short: "Mr. A",
      avatar: "EA",
      role: "Lead principal · founder",
      tier: "founder",
      signLimit: "any",
      // What this principal CANNOT see · ids of vault docs + trip ids
      restrictedDocs: [],
      restrictedTrips: [],
      // Architect lead
      architectId: "co",
      blurb: "The founder's file. Sees everything; signs anything.",
    },
    {
      id: "ma",
      name: "Mrs. Margaret Aldercott",
      short: "Mrs. A",
      avatar: "MA",
      role: "Co-principal · spouse",
      tier: "founder",
      signLimit: "£40,000",
      restrictedDocs: ["kidnap", "med-mr"],
      restrictedTrips: [],
      architectId: "co",
      blurb: "Founder-tier · cannot see Mr A's K&R or his medical file.",
    },
    {
      id: "ba",
      name: "Beatrice Aldercott",
      short: "Bea",
      avatar: "BA",
      role: "Adult child · principal-in-training",
      tier: "trial",
      signLimit: "£8,000",
      // Trial tier · cannot see family financials, K&R, Mr A's medical, tax/residency, FO authority
      restrictedDocs: ["kidnap", "med-mr", "ea-poa", "fo-auth", "tax-uk", "uk-cs"],
      // Trial tier · only sees trips she's on
      restrictedTrips: ["lis", "alf", "par", "ngs"],
      architectId: "rd",
      blurb: "Trial-tier · only her own trips · family financials & K&R hidden.",
    },
    {
      id: "ha",
      name: "Henry Aldercott",
      short: "Henry",
      avatar: "HA",
      role: "Adult child · principal-in-training",
      tier: "trial",
      signLimit: "£8,000",
      restrictedDocs: ["kidnap", "med-mr", "ea-poa", "fo-auth", "tax-uk", "uk-cs"],
      restrictedTrips: ["lis", "alf", "par", "ky"],
      architectId: "dv",
      blurb: "Trial-tier · only his own trips · family financials & K&R hidden.",
    },
  ];

  let listeners = new Set();
  function read() {
    try {
      const v = sessionStorage.getItem(KEY);
      return v && PRINCIPALS.some(p => p.id === v) ? v : DEFAULT;
    } catch (e) { return DEFAULT; }
  }
  function write(id) {
    try {
      if (id === DEFAULT) sessionStorage.removeItem(KEY);
      else sessionStorage.setItem(KEY, id);
    } catch (e) {}
  }
  function emit() { listeners.forEach((fn) => { try { fn(read()); } catch (e) {} }); }

  function list() { return PRINCIPALS; }
  function current() { return read(); }
  function currentRecord() {
    const id = read();
    return PRINCIPALS.find(p => p.id === id) || PRINCIPALS[0];
  }
  function set(id) { if (read() !== id) { write(id); emit(); } }
  function subscribe(fn) { listeners.add(fn); return () => listeners.delete(fn); }
  function isFounder() {
    const r = currentRecord();
    return r && r.tier === "founder";
  }

  // Vault doc visibility · accepts the doc record
  function canViewDoc(doc) {
    if (!doc) return true;
    const r = currentRecord();
    if (!r) return true;
    if (r.restrictedDocs && r.restrictedDocs.includes(doc.id)) return false;
    // Trial-tier additionally hides any doc flagged sensitive
    if (r.tier === "trial" && doc.sensitive) return false;
    return true;
  }

  // Trip visibility · accepts a trip with `principals: ["ea", ...]` or a trip id
  function canViewTrip(tripOrId) {
    const r = currentRecord();
    if (!r) return true;
    const id = typeof tripOrId === "string" ? tripOrId : tripOrId.id;
    const principals = (typeof tripOrId === "object" && tripOrId.principals) || null;
    // Founders see everything
    if (r.tier === "founder") return true;
    // Trial-tier: must be explicitly on the trip's principals list, OR
    // the trip is in their `restrictedTrips` whitelist.
    // restrictedTrips here is a "blocked" list — not a whitelist.
    if (r.restrictedTrips && r.restrictedTrips.includes(id)) return false;
    if (principals) return principals.includes(r.id);
    return true;
  }

  // ── React glue · viewing-as pill that mounts on every page ────────────
  function useActivePrincipal() {
    const [id, setId] = useState(read());
    useEffect(() => subscribe(setId), []);
    return id;
  }

  function ViewingAsPill() {
    const id = useActivePrincipal();
    if (id === DEFAULT) return null;
    const p = PRINCIPALS.find(x => x.id === id);
    if (!p) return null;
    return (
      <div className={`rk-principal-pill rk-principal-pill-${p.tier}`}
           data-screen-label="Viewing-as pill"
           role="status"
           aria-live="polite">
        <span className="rk-principal-pill-av">{p.avatar}</span>
        <span className="rk-principal-pill-meta">
          <span className="k">Viewing as</span>
          <span className="v">{p.name}</span>
        </span>
        <span className="rk-principal-pill-role">{p.role}</span>
        <span className="rk-principal-pill-blurb">{p.blurb}</span>
        <button className="rk-principal-pill-end"
                onClick={() => set(DEFAULT)}>
          Back to founder file
        </button>
      </div>
    );
  }

  function mount() {
    if (document.getElementById("ryoko-principal-host")) return;
    const div = document.createElement("div");
    div.id = "ryoko-principal-host";
    document.body.appendChild(div);
    ReactDOM.createRoot(div).render(<ViewingAsPill />);
  }
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", mount);
  } else {
    mount();
  }

  window.RyokoPrincipal = {
    list, current, currentRecord, set, subscribe,
    canViewDoc, canViewTrip, isFounder, useActive: useActivePrincipal,
  };
})();
