/* shared-library.jsx — SharedLibrary: cohorts + shared files, per-user role.
   Educators create cohorts (→ voucher) and upload material (to everyone or a
   cohort); learners redeem a voucher to join and see their cohort's material;
   trainers see the cohorts assigned to them. One stored copy, three views.
   Portable across all three portals (resolves Icon/toast locally). */
function fmtBytes(n) {
  n = n || 0;
  if (n < 1024) return n + " B";
  if (n < 1048576) return (n / 1024).toFixed(0) + " KB";
  return (n / 1048576).toFixed(1) + " MB";
}
function fileIcon(mime, kind) {
  var m = mime || "";
  if (kind === "deck" || /presentation|powerpoint/.test(m)) return "pptx";
  if (kind === "book" || /pdf/.test(m)) return "book";
  if (/image\//.test(m)) return "image";
  return "file";
}
function isPpt(it) { return it.kind === "deck" || /presentation|powerpoint|presentationml/.test(it.mime || "") || /\.pptx?($|\?)/i.test(it.title || ""); }
function openHref(it) { return isPpt(it) ? ("pptx-view.html?id=" + encodeURIComponent(it.id) + "&t=" + encodeURIComponent(it.title || "")) : window.VHFiles.url(it.id); }

function SharedLibrary() {
  const Icon = window.Icon || window.TIcon || function () { return null; };
  const au = (typeof window !== "undefined" && window.AUTH_USER) || {};
  const isEducator = au.role === "educator";
  const isTrainer = au.role === "trainer";
  const isMarketeer = au.role === "marketeer";
  const canUpload = isEducator || isTrainer || isMarketeer;

  const [items, setItems] = React.useState(null);
  const [cohorts, setCohorts] = React.useState([]);
  const [busy, setBusy] = React.useState(false);
  const [scope, setScope] = React.useState("all");
  const [newName, setNewName] = React.useState("");
  const [voucher, setVoucher] = React.useState("");
  const fileRef = React.useRef(null);

  function toast(m, i) { if (window.eduToast) window.eduToast(m, i); else if (window.vhToast) window.vhToast(m, i); }
  async function refresh() {
    if (window.VHFiles) setItems(await window.VHFiles.list());
    if (window.VHCohorts) setCohorts(await window.VHCohorts.list());
  }
  React.useEffect(() => { refresh(); }, []);

  /* Demo-off honesty: for a learner (not educator/trainer) with demo content
     off, show only files actually assigned to them — their own uploads or a
     cohort they're in — and hide global "everyone" (scope 'all') samples.
     Educators/trainers manage the whole library, and demo-on shows everything. */
  const [, __demoTick] = React.useState(0);
  React.useEffect(() => (window.VHDemo ? window.VHDemo.subscribe(() => __demoTick(x => x + 1)) : undefined), []);
  const demoOn = !window.VHDemo || window.VHDemo.on();
  const isLearner = !isEducator && !isTrainer && !isMarketeer;
  const visibleItems = (items || []).filter(it => demoOn || !isLearner || (it && it.scope && it.scope !== "all"));

  function scopeLabel(s) {
    if (s === "all") return "shared with everyone";
    if (s && s.indexOf("own:") === 0) return "private";
    if (s && s.indexOf("cohort:") === 0) { const c = cohorts.find(x => "cohort:" + x.id === s); return c ? "cohort: " + c.name : "cohort"; }
    return s;
  }
  const uploadTargets = [{ v: "all", label: "Everyone" }].concat((cohorts || []).filter(c => c.role !== "member").map(c => ({ v: "cohort:" + c.id, label: c.name })));

  async function onPick(e) {
    const f = e.target.files && e.target.files[0]; e.target.value = ""; if (!f) return;
    setBusy(true);
    try {
      const kind = /pdf/.test(f.type) ? "book" : /presentation|powerpoint/.test(f.type) ? "deck" : "file";
      await window.VHFiles.upload(f, { title: f.name, kind, scope });
      await refresh();
      toast("Uploaded — " + scopeLabel(scope), "check");
    } catch (err) { toast(err.message || "Upload failed", "x"); }
    setBusy(false);
  }
  async function createCohort() {
    const n = newName.trim(); if (!n) { toast("Enter a cohort name first", "x"); return; } setBusy(true);
    try { const c = await window.VHCohorts.create(n, ""); setNewName(""); await refresh(); toast("Cohort created · voucher " + c.voucher, "check"); }
    catch (e) { toast(e.message, "x"); }
    setBusy(false);
  }
  async function joinCohort() {
    const v = voucher.trim(); if (!v) return; setBusy(true);
    try { const r = await window.VHCohorts.join(v); setVoucher(""); await refresh(); toast("Joined " + ((r.cohort && r.cohort.name) || "cohort"), "check"); }
    catch (e) { toast(e.message, "x"); }
    setBusy(false);
  }
  async function assignTrainer(c) {
    const email = window.prompt("Assign a trainer to “" + c.name + "” by email:"); if (!email) return;
    try { const r = await window.VHCohorts.assign(c.id, email.trim()); await refresh(); toast("Assigned " + ((r.trainer && r.trainer.name) || email), "check"); }
    catch (e) { toast(e.message, "x"); }
  }
  async function remove(it) {
    if (!window.confirm("Remove “" + it.title + "”?")) return;
    await window.VHFiles.remove(it.id); refresh();
  }
  function copyVoucher(v) { try { navigator.clipboard.writeText(v); toast("Voucher copied", "check"); } catch (e) {} }

  const CARD = { background: "var(--surface,#fff)", border: "1px solid var(--line,#e5e9f0)", borderRadius: 14, padding: 22, marginBottom: 18 };
  const PRI = { display: "inline-flex", alignItems: "center", gap: 7, background: "var(--vh-blue-500,#1281c4)", color: "#fff", border: "none", borderRadius: 10, padding: "10px 16px", fontWeight: 700, fontSize: 14, cursor: "pointer" };
  const OUT = { display: "inline-flex", alignItems: "center", gap: 6, background: "transparent", color: "var(--ink,#1c2740)", border: "1px solid var(--line,#e5e9f0)", borderRadius: 9, padding: "8px 13px", fontWeight: 600, fontSize: 13, cursor: "pointer", textDecoration: "none" };
  const FIELD = { padding: "10px 13px", border: "1.5px solid var(--line,#e5e9f0)", borderRadius: 10, fontSize: 14, fontFamily: "inherit", outline: "none", background: "var(--surface,#fff)", color: "var(--ink,#1c2740)" };
  const EY = { fontSize: 11, fontWeight: 800, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--ink-3,#7b899f)", marginBottom: 12 };

  return (
    <div className="vh-in" style={{ maxWidth: 920 }}>
      <div style={{ marginBottom: 18 }}>
        <h1 style={{ fontSize: 24, fontWeight: 800, margin: 0 }}>Shared Library</h1>
        <p style={{ color: "var(--ink-3,#7b899f)", fontSize: 14, marginTop: 4 }}>
          {isEducator ? "Create cohorts, upload material and assign a trainer — everyone on the cohort sees the same content."
            : isTrainer ? "Cohorts assigned to you and their shared material."
            : "Materials shared with you, and cohorts you’ve joined."}
        </p>
      </div>

      {/* ── Cohorts ── */}
      <div style={CARD}>
        <div style={EY}>Cohorts</div>
        {isEducator && (
          <div style={{ display: "flex", gap: 8, marginBottom: 14, flexWrap: "wrap" }}>
            <input value={newName} onChange={e => setNewName(e.target.value)} placeholder="New cohort name (e.g. IPMA-D · Autumn 2026)" style={{ ...FIELD, flex: 1, minWidth: 240 }} onKeyDown={e => { if (e.key === "Enter") createCohort(); }} />
            <button style={{ ...PRI, opacity: busy ? .6 : 1 }} disabled={busy} onClick={createCohort}><Icon name="plus" size={16} />Create cohort</button>
          </div>
        )}
        {!canUpload && (
          <div style={{ display: "flex", gap: 8, marginBottom: 14, flexWrap: "wrap" }}>
            <input value={voucher} onChange={e => setVoucher(e.target.value.toUpperCase())} placeholder="Enter a voucher code (VH-XXXX-XXXX)" style={{ ...FIELD, flex: 1, minWidth: 240, letterSpacing: ".08em", fontFamily: "ui-monospace,monospace" }} onKeyDown={e => { if (e.key === "Enter") joinCohort(); }} />
            <button style={{ ...PRI, opacity: busy ? .6 : 1 }} disabled={busy} onClick={joinCohort}><Icon name="check" size={16} />Join cohort</button>
          </div>
        )}
        {cohorts.length === 0 ? (
          <div style={{ color: "var(--ink-3,#7b899f)", fontSize: 13.5, padding: "8px 0" }}>
            {isEducator ? "No cohorts yet — create one to get a voucher code." : isTrainer ? "No cohorts assigned to you yet." : "You haven’t joined a cohort yet — enter a voucher above."}
          </div>
        ) : cohorts.map(c => (
          <div key={c.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 0", borderBottom: "1px solid var(--line-2,#eef1f6)", flexWrap: "wrap" }}>
            <div style={{ width: 38, height: 38, borderRadius: 10, flex: "none", display: "grid", placeItems: "center", background: "var(--vh-blue-50,#eaf3fb)" }}><Icon name="users" size={18} style={{ color: "var(--vh-blue-500,#1281c4)" }} /></div>
            <div style={{ flex: 1, minWidth: 160 }}>
              <div style={{ fontWeight: 700, fontSize: 14 }}>{c.name}</div>
              <div style={{ color: "var(--ink-3,#7b899f)", fontSize: 12 }}>
                {c.members} member{c.members === 1 ? "" : "s"} · {c.role}{c.trainer_email ? " · trainer: " + c.trainer_email : ""}
              </div>
            </div>
            {c.voucher && (
              <button onClick={() => copyVoucher(c.voucher)} title="Copy voucher" style={{ ...OUT, fontFamily: "ui-monospace,monospace", letterSpacing: ".06em" }}><Icon name="copy" size={13} />{c.voucher}</button>
            )}
            {isEducator && c.role === "owner" && (
              <button onClick={() => assignTrainer(c)} style={OUT}><Icon name="graduation" size={13} />{c.trainer_email ? "Change trainer" : "Assign trainer"}</button>
            )}
          </div>
        ))}
      </div>

      {/* ── Files ── */}
      <div style={CARD}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, marginBottom: 14, flexWrap: "wrap" }}>
          <div style={EY}>Materials</div>
          {canUpload && (
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <select value={scope} onChange={e => setScope(e.target.value)} style={{ ...FIELD, padding: "8px 11px", fontSize: 13 }}>
                {uploadTargets.map(t => <option key={t.v} value={t.v}>{t.label}</option>)}
              </select>
              <input ref={fileRef} type="file" style={{ display: "none" }} onChange={onPick} />
              <button style={{ ...PRI, opacity: busy ? .6 : 1 }} disabled={busy} onClick={() => fileRef.current && fileRef.current.click()}><Icon name="plus" size={16} />{busy ? "Uploading…" : "Upload"}</button>
            </div>
          )}
        </div>
        {items === null && <div style={{ color: "var(--ink-3,#7b899f)", fontSize: 14, padding: "22px 0", textAlign: "center" }}>Loading…</div>}
        {items && visibleItems.length === 0 && <div style={{ color: "var(--ink-3,#7b899f)", fontSize: 14, padding: "30px 0", textAlign: "center" }}>No materials {canUpload ? "yet — upload one above." : "shared with you yet."}</div>}
        {items && visibleItems.map(it => (
          <div key={it.id} style={{ display: "flex", alignItems: "center", gap: 14, padding: "11px 0", borderBottom: "1px solid var(--line-2,#eef1f6)" }}>
            <div style={{ width: 40, height: 40, borderRadius: 10, flex: "none", display: "grid", placeItems: "center", background: "var(--vh-blue-50,#eaf3fb)" }}><Icon name={fileIcon(it.mime, it.kind)} size={19} style={{ color: "var(--vh-blue-500,#1281c4)" }} /></div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontWeight: 700, fontSize: 14, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{it.title}</div>
              <div style={{ color: "var(--ink-3,#7b899f)", fontSize: 12 }}>{fmtBytes(it.size)} · by {it.owner_name || "—"} · {scopeLabel(it.scope)}</div>
            </div>
            <a href={openHref(it)} target="_blank" rel="noopener" style={OUT}><Icon name="eye" size={14} />{isPpt(it) ? "View as HTML" : "Open"}</a>
            {it.owner_id === au.uid && <button onClick={() => remove(it)} title="Remove" style={{ background: "none", border: "none", cursor: "pointer", padding: 6, color: "var(--ink-3,#7b899f)" }}><Icon name="x" size={15} /></button>}
          </div>
        ))}
      </div>
    </div>
  );
}
Object.assign(window, { SharedLibrary });
