// Manage panel — slides in from the right of the board. Two tabs: People
// (contributor share link + roster from /api/boards/:slug/contributors) and
// Settings (recipient share link + lock toggle). Sharing affordances are
// inlined into each tab so the board's top bar stays clean.

function AdminPanel({ palette, onClose, locked, setLocked, onToast, recipientName, slug, contributorLink, recipientLink }) {
  const [tab, setTab] = React.useState("people");
  const [contributors, setContributors] = React.useState(null);   // null = loading
  const [loadError, setLoadError] = React.useState(null);
  const firstName = (recipientName || "Gill").split(/\s+/)[0];
  const isMobile = useIsMobile();

  React.useEffect(() => {
    let cancelled = false;
    if (!slug) return;
    setContributors(null); setLoadError(null);
    API.loadContributors(slug)
      .then((data) => { if (!cancelled) setContributors(data.contributors || []); })
      .catch((err) => { if (!cancelled) setLoadError(err.message || "Couldn't load contributors"); });
    return () => { cancelled = true; };
  }, [slug]);

  const copy = async (text, label) => {
    try {
      await navigator.clipboard.writeText(text);
      onToast(`${label} copied`);
    } catch (_) {
      onToast("Couldn't copy — long-press to copy manually");
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose} style={{ justifyContent: "flex-end" }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: isMobile ? "100vw" : 440,
        height: "100vh", background: "var(--paper)",
        boxShadow: "var(--shadow-3)", display: "flex", flexDirection: "column",
        animation: "slideIn .2s cubic-bezier(.2,.7,.3,1.05)",
      }}>
        <style>{`@keyframes slideIn{from{transform:translateX(20px);opacity:0}to{transform:none;opacity:1}}`}</style>

        <div style={{ padding: "22px 22px 14px", borderBottom: "1px solid var(--line)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
            <div className="chip"><span style={{ color: palette.accent }}>●</span> admin</div>
            <button onClick={onClose} style={{
              width: 28, height: 28, borderRadius: 7, border: 0, background: "transparent",
              cursor: "pointer", color: "var(--ink-2)",
            }}><IconClose size={14} /></button>
          </div>
          <h2 style={{ fontFamily: "var(--serif)", fontSize: 26, margin: 0, fontWeight: 400 }}>
            Manage <em>{firstName}'s</em> board
          </h2>

          <div style={{ display: "flex", gap: 4, marginTop: 16, background: "rgba(31,27,23,0.04)", padding: 3, borderRadius: 9 }}>
            {[
              { id: "people",   label: contributors ? `People (${contributors.length})` : "People" },
              { id: "settings", label: "Settings" },
            ].map((t) => (
              <button key={t.id} onClick={() => setTab(t.id)} style={{
                flex: 1, padding: "7px 8px", borderRadius: 7, border: 0,
                background: tab === t.id ? "#fff" : "transparent",
                color: tab === t.id ? "var(--ink)" : "var(--ink-2)",
                fontFamily: "var(--sans)", fontSize: 12.5, fontWeight: 500,
                cursor: "pointer",
                boxShadow: tab === t.id ? "var(--shadow-1)" : "none",
              }}>{t.label}</button>
            ))}
          </div>
        </div>

        <div style={{ flex: 1, overflowY: "auto", padding: 22 }}>
          {tab === "people" && (
            <PeopleTab
              contributors={contributors}
              loadError={loadError}
              palette={palette}
              contributorLink={contributorLink}
              onCopy={copy}
            />
          )}

          {tab === "settings" && (
            <SettingsTab
              firstName={firstName}
              locked={locked}
              setLocked={setLocked}
              recipientLink={recipientLink}
              palette={palette}
              onCopy={copy}
              slug={slug}
              onToast={onToast}
            />
          )}
        </div>
      </div>
    </div>
  );
}

function PeopleTab({ contributors, loadError, palette, contributorLink, onCopy }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      {contributorLink && (
        <CopyLinkRow
          label="Contributor link"
          hint="Anyone with this link can leave a note."
          url={contributorLink}
          onCopy={() => onCopy(contributorLink, "Contributor link")}
        />
      )}

      <div>
        <div style={{ fontFamily: "var(--serif)", fontSize: 16, lineHeight: 1.2 }}>
          {contributors == null
            ? "Loading…"
            : contributors.length === 1 ? "1 person" : `${contributors.length} people`}
        </div>
        <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 2 }}>
          Anyone who's posted or claimed admin shows up here.
        </div>
      </div>

      {loadError && (
        <div style={{
          padding: "10px 12px", borderRadius: 10, fontSize: 13,
          background: "rgba(232,126,90,0.10)", color: "var(--ink)",
          border: "1px solid rgba(232,126,90,0.35)",
        }}>{loadError}</div>
      )}

      {contributors && contributors.length === 0 && !loadError && (
        <div style={{
          textAlign: "center", padding: "24px 16px",
          color: "var(--ink-3)", lineHeight: 1.6,
        }}>
          <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 18, color: "var(--ink-2)" }}>
            Just you so far.
          </div>
          <div style={{ fontSize: 13, marginTop: 6 }}>Share the link above — they'll show up here once they post.</div>
        </div>
      )}

      {contributors && contributors.map((p) => (
        <PersonRow key={p.id} person={p} palette={palette} />
      ))}
    </div>
  );
}

function SettingsTab({ firstName, locked, setLocked, recipientLink, palette, onCopy, slug, onToast }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
      {recipientLink && (
        <CopyLinkRow
          label={`Recipient link · for ${firstName}`}
          hint={`Send this to ${firstName} when you're ready to reveal. Anyone with the link can view, so share carefully.`}
          url={recipientLink}
          accent
          palette={palette}
          onCopy={() => onCopy(recipientLink, "Recipient link")}
        />
      )}

      <SettingRow
        title={locked ? "Locked" : "Open"}
        sub={locked
          ? "No new notes — only admins can edit and lay things out."
          : "Anyone with the link can add notes."}
        icon={locked ? IconLock : IconUnlock}
        action={<Switch on={locked} onChange={setLocked} />}
      />

      <PasswordResetRow slug={slug} onToast={onToast} />

      <div style={{
        fontFamily: "var(--mono)", fontSize: 10.5, color: "var(--ink-3)",
        letterSpacing: "0.06em", textTransform: "uppercase", lineHeight: 1.6,
      }}>
        Lock the board when you're ready to arrange it for {firstName}.
        The recipient share link still works, so you can keep tweaking
        until the moment you send.
      </div>
    </div>
  );
}

// Collapsed-by-default password reset. Expands into a two-field form
// (new + confirm) with inline validation. PATCH /api/boards/:slug already
// validates length >= 4 server-side and requires admin, so this is just
// the UI surface.
function PasswordResetRow({ slug, onToast }) {
  const [open, setOpen] = React.useState(false);
  const [pw, setPw] = React.useState("");
  const [confirm, setConfirm] = React.useState("");
  const [saving, setSaving] = React.useState(false);
  const MIN = 4;
  const tooShort = pw.length > 0 && pw.length < MIN;
  const mismatch = confirm.length > 0 && pw !== confirm;
  const valid = pw.length >= MIN && pw === confirm;

  const reset = () => { setPw(""); setConfirm(""); };
  const cancel = () => { setOpen(false); reset(); };
  const save = async () => {
    if (!valid || saving) return;
    setSaving(true);
    try {
      await API.patchBoard(slug, { password: pw });
      onToast?.("Password updated");
      setOpen(false);
      reset();
    } catch (err) {
      onToast?.(err.message || "Couldn't update password");
    } finally {
      setSaving(false);
    }
  };

  if (!open) {
    return (
      <SettingRow
        title="Admin password"
        sub="Anyone with this password can claim admin on the board."
        icon={IconLock}
        action={
          <button
            className="btn btn-soft"
            onClick={() => setOpen(true)}
            style={{ padding: "6px 12px", fontSize: 12 }}
          >
            Reset
          </button>
        }
      />
    );
  }

  return (
    <div style={{
      padding: 14, borderRadius: 12,
      border: "1px solid var(--line)", background: "#fff",
    }}>
      <div className="chip" style={{ marginBottom: 6 }}>
        <IconLock size={11} style={{ marginRight: 4 }} /> Reset admin password
      </div>
      <div style={{ color: "var(--ink-3)", fontSize: 12, marginBottom: 10, lineHeight: 1.5 }}>
        Replaces the current password. Existing admins stay signed in until
        they sign out; new admins use this password to claim access.
      </div>
      <input
        className="txt"
        type="password"
        placeholder="New password"
        value={pw}
        autoFocus
        disabled={saving}
        onChange={(e) => setPw(e.target.value)}
      />
      <input
        className="txt"
        type="password"
        placeholder="Confirm password"
        value={confirm}
        disabled={saving}
        onChange={(e) => setConfirm(e.target.value)}
        onKeyDown={(e) => { if (e.key === "Enter" && valid) save(); }}
        style={{ marginTop: 8 }}
      />
      {tooShort && (
        <div style={{ marginTop: 6, fontSize: 11.5, color: "var(--coral)" }}>
          At least {MIN} characters.
        </div>
      )}
      {mismatch && !tooShort && (
        <div style={{ marginTop: 6, fontSize: 11.5, color: "var(--coral)" }}>
          Passwords don't match.
        </div>
      )}
      <div style={{ display: "flex", gap: 8, marginTop: 12, justifyContent: "flex-end" }}>
        <button className="btn btn-ghost" onClick={cancel} disabled={saving}>
          Cancel
        </button>
        <button
          className="btn btn-coral"
          onClick={save}
          disabled={!valid || saving}
          style={{ opacity: !valid || saving ? 0.5 : 1, cursor: !valid || saving ? "not-allowed" : "pointer" }}
        >
          {saving ? "Saving…" : "Save password"}
        </button>
      </div>
    </div>
  );
}

function CopyLinkRow({ label, hint, url, accent, palette, onCopy }) {
  const display = (url || "").replace(/^https?:\/\//, "");
  return (
    <div>
      <div className="chip" style={{ marginBottom: 6, color: accent ? palette.accent : undefined }}>
        {accent && <IconGift size={11} style={{ marginRight: 4 }} />}
        {label}
      </div>
      {hint && (
        <div style={{ color: "var(--ink-3)", fontSize: 12, marginBottom: 8, lineHeight: 1.5 }}>{hint}</div>
      )}
      <div style={{
        display: "flex", alignItems: "center", gap: 0,
        background: accent ? "rgba(232,126,90,0.06)" : "#fff",
        border: accent ? `1px solid ${palette.accent}` : "1px solid var(--line)",
        borderRadius: 12, padding: 4, paddingLeft: 14,
      }}>
        <span style={{
          fontFamily: "var(--mono)", fontSize: 12, color: "var(--ink-2)",
          flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
        }}>
          {display}
        </span>
        <button className={accent ? "btn btn-coral" : "btn btn-primary"} onClick={onCopy}>
          <IconCopy size={13} /> Copy
        </button>
      </div>
    </div>
  );
}

function PersonRow({ person, palette }) {
  const initial = (person.name || "?").trim()[0] || "?";
  const hue = person.hue || hueFromName(person.name || person.id);
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 12,
      padding: "10px 12px", borderRadius: 10, border: "1px solid var(--line)",
      background: "#fff",
    }}>
      <span style={{
        width: 26, height: 26, borderRadius: "50%",
        background: hue, color: "#fff",
        display: "grid", placeItems: "center",
        fontSize: 13, fontWeight: 600,
      }}>{initial}</span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 500, display: "flex", alignItems: "center", gap: 6 }}>
          <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {person.name}
          </span>
          {person.isYou && <Tag>you</Tag>}
        </div>
        <div style={{ fontSize: 11.5, color: "var(--ink-3)", display: "flex", alignItems: "center", gap: 8, marginTop: 2 }}>
          <span>{person.noteCount === 1 ? "1 note" : `${person.noteCount} notes`}</span>
          {person.isAdmin && (
            <>
              <span>·</span>
              <span style={{ color: palette.accent, fontWeight: 500 }}>admin</span>
            </>
          )}
          {person.isCreator && (
            <>
              <span>·</span>
              <span>creator</span>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function Tag({ children }) {
  return (
    <span style={{
      fontFamily: "var(--mono)", fontSize: 9.5, letterSpacing: "0.08em",
      textTransform: "uppercase", color: "var(--ink-2)",
      background: "rgba(31,27,23,0.06)", padding: "2px 6px", borderRadius: 4,
    }}>{children}</span>
  );
}

function SettingRow({ title, sub, icon: Ico, action }) {
  return (
    <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
      <div style={{
        width: 36, height: 36, borderRadius: 10,
        background: "rgba(31,27,23,0.05)",
        display: "grid", placeItems: "center", flex: "none",
      }}><Ico size={16} /></div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 500 }}>{title}</div>
        <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 2 }}>{sub}</div>
      </div>
      {action}
    </div>
  );
}

function Switch({ on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} style={{
      width: 38, height: 22, borderRadius: 999, border: 0,
      background: on ? "var(--coral)" : "rgba(31,27,23,0.18)",
      position: "relative", cursor: "pointer", padding: 0,
      transition: "background .15s",
    }}>
      <span style={{
        position: "absolute", top: 2, left: on ? 18 : 2,
        width: 18, height: 18, borderRadius: "50%", background: "#fff",
        boxShadow: "0 1px 3px rgba(31,27,23,0.25)",
        transition: "left .15s",
      }} />
    </button>
  );
}

Object.assign(window, { AdminPanel });
