/* ============================================================
   beedle data room — guest share surface (loaded by "beedle Data Room.html"
   AFTER app.jsx). A "room" share link (/?share=<token>) opens a read-only,
   curated slice of the data room behind the same lightweight gate the forecaster
   uses (name + email + qualified-investor acknowledgment). On success it boots the
   regular <App> with a synthetic guest identity and server-filtered sections/docs;
   from there an "Open the forecaster" entry hands off to the forecaster page,
   carrying the same session (same-origin sessionStorage).

   Self-contained on purpose: the data-room page doesn't load forecast.css, so the
   gate is inline-styled and reuses only shared primitives (Brand, Icon, the
   InvestorNotice components, BrandContext, App).
   ============================================================ */

// Derive up-to-two-letter initials for the guest avatar/chip from a display name.
function roomInitials(name) {
  const parts = String(name || "").trim().split(/\s+/).filter(Boolean);
  const i = parts.map((w) => w[0]).join("").slice(0, 2).toUpperCase();
  return i || "G";
}

// ---- visitor: the pre-auth gate (name + email + qualified-investor acknowledgment) ----
function RoomShareGate({ meta, onSubmit, busy, error }) {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [ack, setAck] = React.useState(false);
  const [localErr, setLocalErr] = React.useState("");

  const submit = (e) => {
    e.preventDefault();
    if (!name.trim()) { setLocalErr(T("Your name is required.")); return; }
    if (!/^\S+@\S+\.\S+$/.test(email.trim())) { setLocalErr(T("A valid email is required.")); return; }
    if (!ack) { setLocalErr(T("Please confirm your qualification to continue.")); return; }
    setLocalErr("");
    onSubmit({ name: name.trim(), email: email.trim(), investorAck: true });
  };
  const err = localErr || error;
  const inputStyle = { width: "100%", boxSizing: "border-box", padding: "10px 12px", border: "1.5px solid var(--line, #E4E7EA)", borderRadius: 10, fontSize: 14, background: "#fff", fontFamily: "inherit" };
  const labelStyle = { display: "block", fontSize: 12.5, fontWeight: 700, color: "var(--ink-2, #42565F)", marginBottom: 6 };

  return (
    <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center", padding: 20, background: "var(--paper, #F7F4EE)", overflow: "auto" }}>
      <form onSubmit={submit} style={{ width: "100%", maxWidth: 460, background: "#fff", border: "1px solid var(--line, #E4E7EA)", borderRadius: 18, padding: 28, boxShadow: "0 30px 70px -30px rgba(20,36,46,.35)" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <Brand size={38} />
          {typeof LangToggle === "function" && <LangToggle />}
        </div>
        <div className="eyebrow" style={{ marginTop: 16, color: "#0E97C6" }}>{T("Shared data room")}</div>
        <h1 style={{ fontFamily: "var(--serif)", fontWeight: 500, fontSize: 26, lineHeight: 1.15, margin: "6px 0 8px" }}>{meta.title || T("Data room")}</h1>
        <p style={{ fontSize: 14, color: "var(--ink-2, #42565F)", lineHeight: 1.6, margin: "0 0 18px" }}>
          {meta.ownerName ? T("Shared by {name}. ", { name: meta.ownerName }) : ""}
          {T("You'll get read-only access to a curated set of documents")}
          {meta.hasForecaster ? T(", plus an interactive forecaster to explore.") : "."}
        </p>

        <div style={{ marginBottom: 14 }}>
          <label style={labelStyle}>{T("Your name")}</label>
          <input style={inputStyle} value={name} onChange={(e) => setName(e.target.value)} placeholder={T("Jane Smith")} autoComplete="name" />
        </div>
        <div style={{ marginBottom: 16 }}>
          <label style={labelStyle}>{T("Your email")}</label>
          <input style={inputStyle} type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={T("you@firm.com")} autoComplete="email" />
        </div>

        <div style={{ marginBottom: 14 }}>
          <div className="eyebrow" style={{ marginBottom: 8 }}>{T("Important notice")}</div>
          <InvestorNoticeText fontSize={12.5} />
          <div style={{ height: 10 }} />
          <InvestorAckCheckbox checked={ack} onChange={setAck} fontSize={12.5} />
        </div>

        {err && <div style={{ display: "flex", alignItems: "center", gap: 7, color: "var(--red, #C8503A)", fontSize: 13, fontWeight: 600, marginBottom: 12 }}><Icon name="info" size={14} /> {err}</div>}
        <button className="btn btn-primary" type="submit" disabled={busy || !ack} style={{ width: "100%", justifyContent: "center" }}>
          {busy ? T("Opening…") : T("Continue")} {!busy && <Icon name="arrowR" size={16} />}
        </button>
        <div style={{ display: "flex", alignItems: "center", gap: 7, justifyContent: "center", marginTop: 14, fontSize: 12, color: "var(--ink-3, #7E8E94)" }}>
          <Icon name="shield" size={14} /> {T("Read-only — every view is logged")}
        </div>
      </form>
    </div>
  );
}

// ---- visitor: the link exists but is expired/disabled — apologise + take a note ----
function RoomShareGone({ token, kind }) {
  const [email, setEmail] = React.useState("");
  const [note, setNote] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [sent, setSent] = React.useState(false);
  const [err, setErr] = React.useState("");
  const submit = async (e) => {
    e.preventDefault();
    if (!/^\S+@\S+\.\S+$/.test(email.trim())) { setErr(T("A valid email is required.")); return; }
    setErr(""); setBusy(true);
    try { await api.share.leaveNote(token, { email: email.trim(), note: note.trim() }); setSent(true); }
    catch (ex) { setBusy(false); setErr(ex.message || T("Could not send your note. Please try again.")); }
  };
  const inputStyle = { width: "100%", boxSizing: "border-box", padding: "10px 12px", border: "1.5px solid var(--line, #E4E7EA)", borderRadius: 10, fontSize: 14, background: "#fff", fontFamily: "inherit" };
  return (
    <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center", padding: 20, background: "var(--paper, #F7F4EE)", overflow: "auto" }}>
      <form onSubmit={submit} style={{ width: "100%", maxWidth: 460, background: "#fff", border: "1px solid var(--line, #E4E7EA)", borderRadius: 18, padding: 28, boxShadow: "0 30px 70px -30px rgba(20,36,46,.35)" }}>
        <Brand size={38} />
        <div className="eyebrow" style={{ marginTop: 16, color: "#0E97C6" }}>{T("Shared data room")}</div>
        <h1 style={{ fontFamily: "var(--serif)", fontWeight: 500, fontSize: 24, margin: "6px 0 8px" }}>{T("Sorry, this share is no longer available.")}</h1>
        <p style={{ fontSize: 14, color: "var(--ink-2, #42565F)", lineHeight: 1.6, margin: "0 0 18px" }}>
          {kind === "expired" ? T("This link has expired. ") : T("This link has been disabled. ")}
          {T("Leave a note and an admin will get back to you.")}
        </p>
        {sent ? (
          <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "14px 4px", fontWeight: 700, color: "#0E97C6", fontSize: 14 }}>
            <Icon name="check" size={18} sw={2.4} /> {T("Thanks — your note was sent.")}
          </div>
        ) : (
          <React.Fragment>
            <div style={{ marginBottom: 14 }}>
              <input style={inputStyle} type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={T("you@firm.com")} autoComplete="email" />
            </div>
            <div style={{ marginBottom: 14 }}>
              <textarea style={{ ...inputStyle, resize: "vertical", minHeight: 72 }} rows={3} value={note} onChange={(e) => setNote(e.target.value)} placeholder={T("e.g. Could you renew this link? We're reviewing the materials this week.")} />
            </div>
            {err && <div style={{ display: "flex", alignItems: "center", gap: 7, color: "var(--red, #C8503A)", fontSize: 13, fontWeight: 600, marginBottom: 12 }}><Icon name="info" size={14} /> {err}</div>}
            <button className="btn btn-primary" type="submit" disabled={busy} style={{ width: "100%", justifyContent: "center" }}>{busy ? T("Sending…") : T("Send note")}</button>
          </React.Fragment>
        )}
      </form>
    </div>
  );
}

// ---- visitor: token never existed — nothing to route a note to ----
function RoomShareError() {
  return (
    <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center", padding: 20, background: "var(--paper, #F7F4EE)" }}>
      <div style={{ width: "100%", maxWidth: 460, background: "#fff", border: "1px solid var(--line, #E4E7EA)", borderRadius: 18, padding: 28, textAlign: "center", boxShadow: "0 30px 70px -30px rgba(20,36,46,.35)" }}>
        <Brand size={38} />
        <h1 style={{ fontFamily: "var(--serif)", fontWeight: 500, fontSize: 24, margin: "16px 0 8px" }}>{T("This link is invalid.")}</h1>
        <p style={{ fontSize: 14, color: "var(--ink-2, #42565F)", lineHeight: 1.6, margin: 0 }}>{T("Check the address, or ask the person who sent it for a new link.")}</p>
      </div>
    </div>
  );
}

function RoomShareSplash() {
  return (
    <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center", background: "var(--paper, #F7F4EE)" }}>
      <div style={{ textAlign: "center", color: "var(--ink-3, #7E8E94)" }}>
        <Brand size={34} />
        <div style={{ marginTop: 14, fontSize: 13 }}>{T("Opening the data room…")}</div>
      </div>
    </div>
  );
}

// ---- root: walk the gate, then boot <App> on the guest's server-filtered view ----
function RoomShareRoot({ token }) {
  const [company, setCompany] = React.useState(null);
  const [state, setState] = React.useState({ phase: "loading" }); // loading|preauth|ready|gone|invalid
  const [meta, setMeta] = React.useState(null);
  const [boot, setBoot] = React.useState(null);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState("");

  React.useEffect(() => { api.getPublicCompany().then((c) => setCompany(c.company || null)).catch(() => {}); }, []);

  // Build the <App> boot from a session workspace: a synthetic guest `me` (no account)
  // plus the server-filtered, already-graded sections + documents the link grants.
  const buildBoot = async (ws) => {
    const [sections, documents, comp] = await Promise.all([
      api.share.room.sections(token),
      api.share.room.documents(token),
      api.getPublicCompany().then((c) => c.company).catch(() => null),
    ]);
    const name = (ws.name || "Guest").trim();
    return {
      me: { id: "visitor", _id: "visitor", name, email: ws.email, initials: roomInitials(name), dataroomAdmin: false, keyring: [], investorAck: { at: new Date().toISOString() } },
      roles: [],
      company: comp || { name: ws.title || meta && meta.title || T("Data room"), room: T("Shared access") },
      sections,
      documents,
      share: { token, hasForecaster: !!ws.hasForecaster, allowSensitivity: !!ws.allowSensitivity, modelName: ws.modelName || null, title: ws.title || null },
    };
  };

  const toGone = (e) => setState({ phase: "gone", kind: (e.data && e.data.error) === "revoked" ? "revoked" : "expired" });

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      let m;
      try { m = await api.share.meta(token); }
      catch (e) { if (cancelled) return; if (e.status === 410) toGone(e); else setState({ phase: "invalid" }); return; }
      if (cancelled) return;
      // This page only serves room links; a forecast token belongs on /forecaster.
      if (m && m.kind !== "room") { location.replace("/forecaster?share=" + encodeURIComponent(token)); return; }
      setMeta(m);
      if (api.share.sessionToken(token)) {
        try {
          const ws = await api.share.getWorkspace(token);
          const b = await buildBoot(ws);
          if (cancelled) return;
          setBoot(b); setState({ phase: "ready" });
          return;
        } catch (_) { api.share.clearSession(token); } // stale/expired session → back to the gate
      }
      if (!cancelled) setState({ phase: "preauth" });
    })();
    return () => { cancelled = true; };
  }, [token]);

  // Keep "time used" current while the guest is here (paused when the tab is hidden).
  React.useEffect(() => {
    if (state.phase !== "ready") return;
    const ping = () => { if (!document.hidden) api.share.room.heartbeat(token); };
    ping();
    const id = setInterval(ping, 30000);
    return () => clearInterval(id);
  }, [state.phase, token]);

  const submit = async ({ name, email, investorAck }) => {
    setBusy(true); setError("");
    try {
      const ws = await api.share.createSession(token, { name, email, investorAck });
      const b = await buildBoot(ws);
      setBoot(b); setState({ phase: "ready" });
    } catch (e) {
      setBusy(false);
      if (e.status === 410) toGone(e);
      else if (e.status === 404) setState({ phase: "invalid" });
      else setError(e.message || T("Something went wrong. Please try again."));
    }
  };

  let content;
  if (state.phase === "loading") content = <RoomShareSplash />;
  else if (state.phase === "invalid") content = <RoomShareError />;
  else if (state.phase === "gone") content = <RoomShareGone token={token} kind={state.kind} />;
  else if (state.phase === "preauth") content = <RoomShareGate meta={meta} onSubmit={submit} busy={busy} error={error} />;
  else content = <App boot={boot} t={{ homeLayout: "grid", viewerChrome: "framed" }} setTweak={() => {}} reload={() => {}} />;
  return <BrandContext.Provider value={company}>{content}</BrandContext.Provider>;
}

// app.jsx (loaded just before this file) resolved the token and skipped mounting the
// authenticated <Root/> when one is present — mount the guest room here instead.
if (window.__roomShareToken) {
  ReactDOM.createRoot(document.getElementById("root")).render(<RoomShareRoot token={window.__roomShareToken} />);
}
