/* ============================================================
   Manager · Members roster
   The tour manager reviews each member's GHIN + Handicap Index,
   carries last week's value forward, confirms or edits it, and
   the change is saved back to the member's profile.
   ============================================================ */
function RosterScreen({ ctx }) {
  const Y = window.YCC;
  const { toast } = ctx;
  const db = window.YCCdb;
  const ready = !!(db && db.isConfigured && db.isConfigured());

  const [rows, setRows] = useState(null); // null = loading
  const [edits, setEdits] = useState({}); // id -> {handicap_index, ghin, tee}
  const [savingId, setSavingId] = useState(null);
  const [pwTarget, setPwTarget] = useState(null); // member being reset
  const [pwVal, setPwVal] = useState("");
  const [pwState, setPwState] = useState({ busy: false, msg: "", ok: null });

  function openReset(m) { setPwTarget(m); setPwVal(""); setPwState({ busy: false, msg: "", ok: null }); }
  function doReset() {
    if (pwVal.length < 6) { setPwState({ busy: false, ok: false, msg: "At least 6 characters." }); return; }
    setPwState({ busy: true, msg: "", ok: null });
    db.resetMemberPassword(pwTarget.email, pwVal).then((res) => {
      if (res && res.ok) setPwState({ busy: false, ok: true, msg: "Password set. Give it to the member to sign in." });
      else setPwState({ busy: false, ok: false, msg: (res && res.error) || "Failed." });
    });
  }

  function load() {
    if (!ready) { setRows([]); return; }
    setRows(null);
    db.getMembers().then((list) => setRows(list)).catch(() => setRows([]));
  }
  useEffect(() => { load(); }, []);

  function setEdit(id, patch) { setEdits((e) => ({ ...e, [id]: { ...e[id], ...patch } })); }
  function valOf(m, field) {
    const e = edits[m.id] || {};
    if (field in e) return e[field];
    return m[field] == null ? "" : m[field];
  }
  function dirty(m) { return !!edits[m.id]; }

  function save(m, confirmOnly) {
    const e = edits[m.id] || {};
    const hiRaw = confirmOnly ? m.handicap_index : (e.handicap_index ?? m.handicap_index);
    const hi = hiRaw === "" || hiRaw == null ? null : Number(hiRaw);
    const row = {
      id: m.id, email: m.email,
      first_name: m.first_name || "", last_name: m.last_name || "",
      ghin: (confirmOnly ? m.ghin : (e.ghin ?? m.ghin)) || null,
      handicap_index: hi,
      tee: (confirmOnly ? m.tee : (e.tee ?? m.tee)) || null,
      phone: m.phone || null, tier: m.tier || "Member",
      handicap_confirmed_at: new Date().toISOString(),
    };
    setSavingId(m.id);
    db.upsertMember(row).then((res) => {
      setSavingId(null);
      if (res && res.error) { toast("Save failed: " + (res.error.message || res.error)); return; }
      toast(confirmOnly ? "Confirmed for this week" : `Updated ${m.first_name || m.email}`);
      setEdits((all) => { const c = { ...all }; delete c[m.id]; return c; });
      setRows((list) => list.map((x) => x.id === m.id ? { ...x, ...row } : x));
    }).catch(() => { setSavingId(null); toast("Save failed."); });
  }

  function confirmedLabel(m) {
    if (!m.handicap_confirmed_at) return { txt: "Confirm to enable", stale: true };
    const week = Y.confirmedForWeek(m.handicap_confirmed_at, Y.SAT);
    const d = new Date(m.handicap_confirmed_at);
    const days = Math.floor((Date.now() - d.getTime()) / 86400000);
    if (!week) return { txt: "Reconfirm this week", stale: true };
    return { txt: days === 0 ? "Available · today" : days === 1 ? "Available · yesterday" : `Available · ${days}d ago`, stale: false };
  }

  const dot = { Blue: "#2f5db0", White: "#c7c8b3", Green: "#3a7a4f", Gold: "#b08d4f", Red: "#9e3b2f" };

  return (
    <div className="page fade-in">
      <div className="page-head" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 16 }}>
        <div>
          <div className="eyebrow">Manager · Members</div>
          <h1 style={{ marginTop: 6 }}>Member handicaps</h1>
          <p>Each week, review every member's Handicap Index — last week's value carries forward. Edit if it changed, then Confirm. Saved values stay in each member's profile.</p>
        </div>
        <button className="btn btn-ghost" onClick={load}><Icon name="swap" size={15} /> Refresh list</button>
      </div>

      {!ready && (
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "12px 16px", borderRadius: "var(--radius)", background: "color-mix(in srgb,var(--danger) 10%,var(--surface))", border: "1px solid color-mix(in srgb,var(--danger) 30%,transparent)", marginBottom: 18, fontSize: 13 }}>
          <Icon name="info" size={16} style={{ color: "var(--danger)" }} />
          <span>Connect Supabase (keys in <code>config.js</code>) to load and save the member roster.</span>
        </div>
      )}

      {rows === null ? (
        <div className="card card-pad" style={{ textAlign: "center", padding: 48 }}>
          <div className="faint">Loading members…</div>
        </div>
      ) : rows.length === 0 ? (
        <div className="card card-pad" style={{ textAlign: "center", padding: 48 }}>
          <Icon name="users" size={28} style={{ color: "var(--ink-faint)" }} />
          <h3 className="serif" style={{ fontSize: 21, marginTop: 12 }}>No members yet</h3>
          <p className="muted" style={{ fontSize: 14, marginTop: 6 }}>Members appear here once they sign up and save their profile.</p>
        </div>
      ) : (
        <div className="card" style={{ overflow: "hidden" }}>
          <div className="scroll-x">
            <table style={{ borderCollapse: "collapse", width: "100%", minWidth: 720, fontSize: 13.5 }}>
              <thead>
                <tr style={{ background: "var(--surface-2)", textAlign: "left" }}>
                  {["Member", "GHIN", "Handicap Index", "Tees", "Status", ""].map((h, i) => (
                    <th key={i} style={{ padding: "12px 14px", fontSize: 11.5, fontWeight: 700, letterSpacing: ".05em", textTransform: "uppercase", color: "var(--ink-soft)", whiteSpace: "nowrap" }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {rows.map((m) => {
                  const cl = confirmedLabel(m);
                  const name = `${m.first_name || ""} ${m.last_name || ""}`.trim() || m.email;
                  return (
                    <tr key={m.id} style={{ borderTop: "1px solid var(--line)" }}>
                      <td style={{ padding: "11px 14px" }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                          <Avatar initials={(name || "?").split(/\s+/).map(s => s[0]).join("").slice(0, 2).toUpperCase()} size={30} />
                          <div style={{ minWidth: 0 }}>
                            <div style={{ fontWeight: 700, whiteSpace: "nowrap" }}>{name}</div>
                            <div className="faint" style={{ fontSize: 11.5, whiteSpace: "nowrap" }}>{m.email}</div>
                          </div>
                        </div>
                      </td>
                      <td style={{ padding: "11px 14px" }}>
                        <input className="input" value={valOf(m, "ghin")} onChange={(e) => setEdit(m.id, { ghin: e.target.value.replace(/[^0-9]/g, "").slice(0, 8) })} style={{ width: 110, padding: "7px 10px", fontFamily: "ui-monospace, monospace" }} placeholder="—" />
                      </td>
                      <td style={{ padding: "11px 14px" }}>
                        <input className="input" inputMode="decimal" value={valOf(m, "handicap_index")} onChange={(e) => setEdit(m.id, { handicap_index: e.target.value.replace(/[^0-9.]/g, "").slice(0, 4) })} style={{ width: 76, padding: "7px 10px", fontWeight: 700 }} placeholder="—" />
                      </td>
                      <td style={{ padding: "11px 14px" }}>
                        <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                          <span style={{ width: 11, height: 11, borderRadius: "50%", background: dot[valOf(m, "tee")] || "var(--line-strong)", border: "1px solid rgba(0,0,0,.15)" }}></span>
                          <select value={valOf(m, "tee") || "White"} onChange={(e) => setEdit(m.id, { tee: e.target.value })} style={{ border: "1px solid var(--line-strong)", borderRadius: 7, padding: "6px 8px", fontFamily: "var(--font-body)", fontSize: 12.5, fontWeight: 600, background: "var(--surface)" }}>
                            {["Blue", "White", "Green", "Gold", "Red"].map(t => <option key={t} value={t}>{t}</option>)}
                          </select>
                        </span>
                      </td>
                      <td style={{ padding: "11px 14px" }}>
                        <span className="pill" style={{ background: cl.stale ? "color-mix(in srgb,var(--danger) 14%,transparent)" : "var(--brand-soft)", color: cl.stale ? "var(--danger)" : "var(--brand)", whiteSpace: "nowrap" }}>{cl.txt}</span>
                      </td>
                      <td style={{ padding: "11px 14px", textAlign: "right", whiteSpace: "nowrap" }}>
                        <span style={{ display: "inline-flex", gap: 6, alignItems: "center" }}>
                          <button className="btn btn-ghost btn-sm" title="Reset password" style={{ padding: "7px 9px" }} onClick={() => openReset(m)}><Icon name="shield" size={14} /></button>
                          {dirty(m)
                            ? <button className="btn btn-primary btn-sm" disabled={savingId === m.id} onClick={() => save(m, false)}>{savingId === m.id ? "Saving…" : <><Icon name="check" size={13} /> Save</>}</button>
                            : <button className="btn btn-quiet btn-sm" disabled={savingId === m.id} onClick={() => save(m, true)}>{savingId === m.id ? "…" : <><Icon name="check" size={13} /> Confirm</>}</button>}
                        </span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {pwTarget && (
        <Modal onClose={() => setPwTarget(null)}>
          <ModalHead title="Reset member password" sub={pwTarget.email} onClose={() => setPwTarget(null)} />
          <div style={{ padding: 24 }}>
            <p className="muted" style={{ fontSize: 13.5, margin: "0 0 16px", lineHeight: 1.5 }}>
              Set a temporary password for <strong>{`${pwTarget.first_name || ""} ${pwTarget.last_name || ""}`.trim() || pwTarget.email}</strong>, then share it with them. They can change it later from their profile.
            </p>
            <div className="field">
              <label>Temporary password</label>
              <div style={{ display: "flex", gap: 8 }}>
                <input className="input" value={pwVal} onChange={(e) => setPwVal(e.target.value)} placeholder="At least 6 characters" style={{ flex: 1 }} />
                <button type="button" className="btn btn-ghost" onClick={() => setPwVal(Math.random().toString(36).slice(2, 10))}>Generate</button>
              </div>
            </div>
            {pwState.msg && (
              <div style={{ fontSize: 13, fontWeight: 600, color: pwState.ok ? "var(--ok)" : "var(--danger)", display: "flex", alignItems: "center", gap: 7, margin: "4px 0 6px" }}>
                <Icon name={pwState.ok ? "checkCircle" : "info"} size={15} /> {pwState.msg}
              </div>
            )}
            <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, marginTop: 14 }}>
              <button className="btn btn-ghost" onClick={() => setPwTarget(null)}>{pwState.ok ? "Done" : "Cancel"}</button>
              <button className="btn btn-primary" disabled={pwState.busy || pwState.ok} onClick={doReset}>{pwState.busy ? "Setting…" : "Set password"}</button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}

Object.assign(window, { RosterScreen });
