/* admin.jsx — admin portal at #admin
 * Password gate → guest list with add/remove/reset, selection stats, and photo gallery.
 */

const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React;

function AdminGate({ onAuth }) {
  const [pw, setPw] = useStateA("");
  const [err, setErr] = useStateA("");
  const [busy, setBusy] = useStateA(false);

  async function submit(e) {
    e.preventDefault();
    setBusy(true);
    const ok = await weddingAPI.adminAuth(pw);
    setBusy(false);
    if (ok) {
      onAuth();
    } else {
      setErr("Incorrect password");
      setPw("");
    }
  }

  return (
    <div className="gate">
      <form className="gate-card" onSubmit={submit}>
        <div className="mono">Restricted area</div>
        <h1 className="serif">Admin</h1>
        <div className="sub">Hosts only — enter the password to manage RSVPs.</div>
        <input
          className="code-input"
          type="password"
          value={pw}
          onChange={(e) => { setPw(e.target.value); setErr(""); }}
          placeholder="••••••••••"
          autoFocus
        />
        <button className="code-btn" type="submit" style={{ marginTop: 24 }} disabled={busy}>
          {busy ? "Checking…" : "Unlock"}
        </button>
        <div className="code-msg">{err}</div>
        <div style={{ marginTop: 20, fontSize: 10.5, letterSpacing: "0.28em", textTransform: "uppercase", color: "rgba(255,255,255,0.55)" }}>
          <a href="#" style={{ borderBottom: "1px solid rgba(255,255,255,0.4)", paddingBottom: 2 }}>← Back to invitation</a>
        </div>
      </form>
    </div>
  );
}

function StatCard({ k, v, delta }) {
  return (
    <div className="stat">
      <div className="k">{k}</div>
      <div className="v">{v}</div>
      {delta ? <div className="delta">{delta}</div> : null}
    </div>
  );
}

function Bar({ label, count, total, color }) {
  const pct = total > 0 ? Math.round((count / total) * 100) : 0;
  return (
    <div className="bar-row">
      <div className="lbl">{label}</div>
      <div className="track">
        <div className="fill" style={{ width: pct + "%", background: color || "var(--accent)" }}></div>
      </div>
      <div className="num">{count}</div>
    </div>
  );
}

function AddGuestForm({ onAdded }) {
  const [name, setName] = useStateA("");
  const [isFamily, setIsFamily] = useStateA(false);
  const [members, setMembers] = useStateA([{ name: "", isChild: false }]);
  const [last, setLast] = useStateA(null);
  const [busy, setBusy] = useStateA(false);

  function updateMember(i, patch) {
    setMembers(members.map((m, j) => (i === j ? { ...m, ...patch } : m)));
  }
  function addMemberRow() {
    setMembers([...members, { name: "", isChild: false }]);
  }
  function removeMemberRow(i) {
    setMembers(members.filter((_, j) => j !== i));
  }

  async function submit(e) {
    if (e) e.preventDefault();
    if (!name.trim()) return;
    setBusy(true);
    const opts = {};
    if (isFamily) {
      opts.members = members
        .filter((m) => m.name.trim())
        .map((m) => ({ name: m.name.trim(), isChild: m.isChild }));
      if (opts.members.length < 1) {
        setBusy(false);
        alert("Add at least one person to the family.");
        return;
      }
    }
    const g = await weddingAPI.addGuest(name, opts);
    setBusy(false);
    setLast(g);
    setName("");
    setIsFamily(false);
    setMembers([{ name: "", isChild: false }]);
    onAdded();
  }

  function copy() {
    if (!last) return;
    navigator.clipboard.writeText(last.code).catch(() => {});
  }

  return (
    <div className="panel">
      <h3 className="serif">Add a guest</h3>
      <div className="sub">A unique code is generated automatically</div>
      <form onSubmit={submit}>
        <div className="add-row">
          <input
            value={name}
            onChange={(e) => setName(e.target.value)}
            placeholder={isFamily ? "Party / family name (e.g. The Carters)" : "Guest name (e.g. Sam Carter)"}
          />
        </div>

        <label className="family-toggle">
          <input
            type="checkbox"
            checked={isFamily}
            onChange={(e) => setIsFamily(e.target.checked)}
          />
          <span>This invitation is for a family / party</span>
        </label>

        {isFamily ? (
          <div className="member-list">
            <div className="member-list-head">
              <span>People on this invite</span>
              <button type="button" className="link-btn" onClick={addMemberRow}>+ Add person</button>
            </div>
            {members.map((m, i) => (
              <div key={i} className="member-row">
                <input
                  className="member-name"
                  value={m.name}
                  onChange={(e) => updateMember(i, { name: e.target.value })}
                  placeholder={`Person ${i + 1} — full name`}
                />
                <label className="child-toggle">
                  <input
                    type="checkbox"
                    checked={m.isChild}
                    onChange={(e) => updateMember(i, { isChild: e.target.checked })}
                  />
                  <span>Child</span>
                </label>
                <button
                  type="button"
                  className="member-remove"
                  onClick={() => removeMemberRow(i)}
                  disabled={members.length === 1}
                  title="Remove person"
                >×</button>
              </div>
            ))}
            <div className="member-hint">
              Children get the meal picker but skip the drinks question — they're set to non-alcoholic automatically.
            </div>
          </div>
        ) : null}

        <button type="submit" className="add-submit" disabled={busy || !name.trim()}>
          {busy ? "Adding…" : (isFamily ? `Add party & generate code` : "Add guest & generate code")}
        </button>
      </form>

      {last ? (
        <div className="last-issued">
          <div className="lbl">Code for {last.name}</div>
          <div className="code">{last.code}</div>
          {last.members && last.members.length ? (
            <div className="last-members">
              {last.members.length} {last.members.length === 1 ? "person" : "people"} on this invite
            </div>
          ) : null}
          <button className="copy" onClick={copy}>Copy code</button>
        </div>
      ) : null}

      <div style={{ marginTop: 22, paddingTop: 18, borderTop: "1px solid var(--rule-soft)", fontSize: 12, color: "var(--ink-mute)" }}>
        Share the code with the guest. They'll use it to open the website and submit their RSVP.
      </div>
    </div>
  );
}

function GuestRow({ g, onRemove, onReset, expanded, onToggle }) {
  const isParty = g.members && g.members.length > 0;
  return (
    <React.Fragment>
      <tr onClick={onToggle} style={{ cursor: "pointer" }}>
        <td>
          <div className="guest-code">{g.code}</div>
        </td>
        <td>
          <div>{g.name}</div>
          {isParty ? (
            <div style={{ fontSize: 11, color: "var(--ink-mute)", marginTop: 4, letterSpacing: "0.04em" }}>
              {g.members.length} on invite
              {g.members.some((m) => m.isChild)
                ? ` · ${g.members.filter((m) => m.isChild).length} ${g.members.filter((m) => m.isChild).length === 1 ? "child" : "children"}`
                : ""}
              {g.members.some((m) => m.status === "declined")
                ? ` · ${g.members.filter((m) => m.status === "declined").length} declined`
                : ""}
            </div>
          ) : null}
        </td>
        <td>
          <span className={"status-pill " + (g.status || "pending")}>
            <span style={{ width: 6, height: 6, borderRadius: "50%", background: "currentColor" }}></span>
            {g.status || "pending"}
          </span>
        </td>
        <td>
          {isParty ? (
            <div className="meal-chip" style={{ color: "var(--ink-mute)" }}>
              {summarise(g.members.filter((m) => m.status !== "declined").map((m) => m.meal).filter(Boolean))}
            </div>
          ) : (
            <div className="meal-chip">{g.meal ? g.meal.toUpperCase() : "—"}</div>
          )}
        </td>
        <td>
          {isParty ? (
            <div className="drink-chip" style={{ color: "var(--ink-mute)" }}>
              {summarise(g.members.filter((m) => m.status !== "declined").map((m) => m.drinks).filter(Boolean))}
            </div>
          ) : (
            <div className="drink-chip">{g.drinks ? g.drinks.toUpperCase() : "—"}</div>
          )}
        </td>
        <td style={{ textAlign: "right" }}>
          <div className="row-actions">
            <button onClick={(e) => { e.stopPropagation(); navigator.clipboard.writeText(g.code).catch(() => {}); }}>Copy</button>
            <button onClick={(e) => { e.stopPropagation(); onReset(g); }}>Reset</button>
            <button className="danger" onClick={(e) => { e.stopPropagation(); onRemove(g); }}>Remove</button>
          </div>
        </td>
      </tr>
      {expanded ? (
        <tr>
          <td colSpan="6" className="detail-strip">
            {isParty ? (
              <div className="member-detail-list">
                {g.members.map((m) => (
                  <div key={m.id} className={"member-detail" + (m.status === "declined" ? " declined" : "")}>
                    <div className="md-name">
                      {m.name}
                      {m.isChild ? <span className="md-child">Child</span> : null}
                      {m.status === "declined" ? <span className="md-child" style={{ borderColor: "#aa5a5a", color: "#8a4f4f" }}>Declined</span> : null}
                    </div>
                    {m.status === "declined" ? (
                      <div className="md-cell" style={{ gridColumn: "span 2", color: "var(--ink-mute)", fontStyle: "italic" }}>
                        Can't make it
                      </div>
                    ) : (
                      <React.Fragment>
                        <div className="md-cell"><span className="k">Meal</span>{m.meal || "—"}</div>
                        <div className="md-cell"><span className="k">Drinks</span>{m.drinks || "—"}</div>
                      </React.Fragment>
                    )}
                    {m.allergies && m.status !== "declined" ? (
                      <div className="md-allergies">
                        <span className="k">Allergies</span>{m.allergies}
                      </div>
                    ) : null}
                  </div>
                ))}
                {g.allergies || g.song || g.message ? (
                  <div className="party-notes">
                    {g.allergies ? <div><span className="k">Allergies</span>{g.allergies}</div> : null}
                    {g.song     ? <div><span className="k">Song</span>{g.song}</div> : null}
                    {g.message  ? <div><span className="k">Message</span>"{g.message}"</div> : null}
                  </div>
                ) : null}
              </div>
            ) : g.allergies || g.song || g.message ? (
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 20 }}>
                <div><span className="k">Allergies</span>{g.allergies || "—"}</div>
                <div><span className="k">Song</span>{g.song || "—"}</div>
                <div><span className="k">Message</span>{g.message ? "\"" + g.message + "\"" : "—"}</div>
              </div>
            ) : (
              <em>No additional notes from this guest yet.</em>
            )}
            {g.registeredAt ? (
              <div style={{ marginTop: 10, fontSize: 11, color: "var(--ink-mute)" }}>
                <span className="k">Registered</span>
                {new Date(g.registeredAt).toLocaleString()}
              </div>
            ) : null}
          </td>
        </tr>
      ) : null}
    </React.Fragment>
  );
}

function summarise(values) {
  if (!values.length) return "—";
  const counts = {};
  values.forEach((v) => { counts[v] = (counts[v] || 0) + 1; });
  return Object.entries(counts)
    .map(([k, v]) => `${v}× ${k.toUpperCase().slice(0, 4)}`)
    .join(" · ");
}

function AdminDashboard({ onLogout }) {
  const [guests, setGuests] = useStateA([]);
  const [stats, setStats] = useStateA({ total: 0, partyCount: 0, responded: 0, attending: 0, declined: 0, meals: {}, drinks: {}, kids: { count: 0 } });
  const [photos, setPhotos] = useStateA([]);
  const [tab, setTab] = useStateA("guests");
  const [filter, setFilter] = useStateA("");
  const [statusFilter, setStatusFilter] = useStateA("all");
  const [expanded, setExpanded] = useStateA(new Set());

  async function refresh() {
    const [g, s, p] = await Promise.all([
      weddingAPI.listGuests(),
      weddingAPI.stats(),
      weddingAPI.listPhotos()
    ]);
    setGuests(g);
    setStats(s);
    setPhotos(p);
  }

  useEffectA(() => { refresh(); }, []);

  async function handleRemove(g) {
    if (!confirm(`Remove ${g.name} (${g.code}) from the list?`)) return;
    await weddingAPI.removeGuest(g.code);
    refresh();
  }
  async function handleReset(g) {
    if (!confirm(`Reset ${g.name}'s RSVP so they can fill it in again?`)) return;
    await weddingAPI.resetRSVP(g.code);
    refresh();
  }

  function toggleRow(code) {
    const next = new Set(expanded);
    if (next.has(code)) next.delete(code); else next.add(code);
    setExpanded(next);
  }

  function exportCsv() {
    const rows = [
      ["Code", "Party", "Person", "IsChild", "PartyStatus", "PersonStatus", "Meal", "Drinks", "Allergies", "Song", "Message", "RegisteredAt"]
    ];
    guests.forEach((g) => {
      const reg = g.registeredAt ? new Date(g.registeredAt).toISOString() : "";
      if (g.members && g.members.length) {
        g.members.forEach((m) => {
          rows.push([
            g.code, g.name, m.name, m.isChild ? "yes" : "no",
            g.status || "pending",
            m.status || "attending",
            m.meal || "", m.drinks || "",
            m.allergies || g.allergies || "",
            g.song || "", g.message || "", reg
          ]);
        });
      } else {
        rows.push([
          g.code, "", g.name, "no",
          g.status || "pending",
          g.status || "pending",
          g.meal || "", g.drinks || "",
          g.allergies || "", g.song || "", g.message || "", reg
        ]);
      }
    });
    const csv = rows.map((r) =>
      r.map((c) => `"${String(c).replace(/"/g, '""')}"`).join(",")
    ).join("\n");
    const blob = new Blob([csv], { type: "text/csv" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "rsvp-list.csv";
    a.click();
  }

  const filtered = useMemoA(() => {
    const q = filter.trim().toLowerCase();
    return guests.filter((g) => {
      if (statusFilter !== "all" && (g.status || "pending") !== statusFilter) return false;
      if (!q) return true;
      return g.code.toLowerCase().includes(q) || g.name.toLowerCase().includes(q);
    });
  }, [guests, filter, statusFilter]);

  return (
    <div className="admin-wrap">
      <div className="admin-shell">
        <div className="admin-header">
          <div>
            <div className="admin-eyebrow">Wedding admin</div>
            <h1 className="admin-title">Rhyan & Alex · Guest manager</h1>
          </div>
          <div className="admin-actions">
            <button className="btn-ghost" onClick={exportCsv}>Export CSV</button>
            <button className="btn-ghost" onClick={() => { weddingAPI.adminLogout(); onLogout(); }}>
              Lock & exit
            </button>
          </div>
        </div>

        <div className="admin-stats">
          <StatCard k="Headcount" v={stats.total} delta={stats.partyCount ? `${stats.partyCount} ${stats.partyCount === 1 ? "invite" : "invites"}` : null} />
          <StatCard k="Responded" v={stats.responded} delta={`${stats.partyCount ? Math.round((stats.responded / stats.partyCount) * 100) : 0}% of invites`} />
          <StatCard k="Attending" v={stats.attending} delta={stats.kids && stats.kids.count ? `${stats.kids.count} ${stats.kids.count === 1 ? "child" : "children"}` : "people"} />
          <StatCard k="Declined"  v={stats.declined} />
          <StatCard k="Awaiting"  v={Math.max(0, stats.partyCount - stats.responded)} delta="not yet RSVP'd" />
        </div>

        <div className="admin-grid">
          <div>
            <AddGuestForm onAdded={refresh} />
            <div className="panel" style={{ marginTop: 22 }}>
              <h3 className="serif">Meal selections</h3>
              <div className="sub">Among confirmed guests</div>
              <div className="bars">
                <Bar label="Meat"        count={stats.meals.meat || 0}        total={stats.attending} color="#b08864" />
                <Bar label="Vegetarian"  count={stats.meals.vegetarian || 0}  total={stats.attending} color="#7e8d6a" />
                <Bar label="Vegan"       count={stats.meals.vegan || 0}       total={stats.attending} color="#5a7048" />
              </div>
              <h3 className="serif" style={{ marginTop: 22 }}>Drinks</h3>
              <div className="bars">
                <Bar label="Alcoholic"      count={stats.drinks.alcoholic || 0}       total={stats.attending} color="#8a6647" />
                <Bar label="Non-alcoholic"  count={stats.drinks["non-alcoholic"] || 0} total={stats.attending} color="#7a8aa5" />
              </div>
            </div>
          </div>

          <div className="panel">
            <div className="admin-tabs">
              <button className={"admin-tab" + (tab === "guests" ? " active" : "")} onClick={() => setTab("guests")}>
                Guests ({guests.length})
              </button>
              <button className={"admin-tab" + (tab === "photos" ? " active" : "")} onClick={() => setTab("photos")}>
                Photos ({photos.length})
              </button>
            </div>

            {tab === "guests" ? (
              <React.Fragment>
                <div className="filter-bar">
                  <input
                    value={filter}
                    onChange={(e) => setFilter(e.target.value)}
                    placeholder="Search by name or code…"
                  />
                  <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
                    <option value="all">All statuses</option>
                    <option value="pending">Pending</option>
                    <option value="attending">Attending</option>
                    <option value="declined">Declined</option>
                  </select>
                </div>
                <table className="guest-table">
                  <thead>
                    <tr>
                      <th style={{ width: 110 }}>Code</th>
                      <th>Name</th>
                      <th style={{ width: 130 }}>Status</th>
                      <th style={{ width: 110 }}>Meal</th>
                      <th style={{ width: 140 }}>Drinks</th>
                      <th style={{ textAlign: "right", width: 200 }}></th>
                    </tr>
                  </thead>
                  <tbody>
                    {filtered.length === 0 ? (
                      <tr><td colSpan="6" style={{ textAlign: "center", padding: 32, color: "var(--ink-mute)" }}>
                        No guests match — try clearing the filter.
                      </td></tr>
                    ) : filtered.map((g) => (
                      <GuestRow
                        key={g.code}
                        g={g}
                        expanded={expanded.has(g.code)}
                        onToggle={() => toggleRow(g.code)}
                        onRemove={handleRemove}
                        onReset={handleReset}
                      />
                    ))}
                  </tbody>
                </table>
              </React.Fragment>
            ) : (
              <PhotoGrid photos={photos} />
            )}
          </div>
        </div>

        <div style={{ marginTop: 60, paddingTop: 24, borderTop: "1px solid var(--rule-soft)", display: "flex", justifyContent: "space-between", color: "var(--ink-mute)", fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase" }}>
          <span>Prototype · data stored locally in this browser</span>
          <button className="btn-link" onClick={() => {
            if (confirm("Wipe all guests and photos? This cannot be undone in this browser.")) {
              weddingAPI._resetAll();
              location.reload();
            }
          }}>Wipe demo data</button>
        </div>
      </div>
    </div>
  );
}

function PhotoGrid({ photos }) {
  if (photos.length === 0) {
    return (
      <div style={{ textAlign: "center", padding: 60, color: "var(--ink-mute)" }}>
        <div style={{ fontFamily: "var(--serif)", fontSize: 36, marginBottom: 12 }}>·</div>
        <p>No photos uploaded yet. They'll appear here as guests share theirs.</p>
      </div>
    );
  }
  return (
    <div className="gallery" style={{ gridTemplateColumns: "repeat(3, 1fr)", maxWidth: "100%" }}>
      {photos.map((p) => (
        <div key={p.id} className="gallery-tile" style={{ background: `center/cover no-repeat url(${p.dataUrl})` }}>
          <span style={{ background: "rgba(0,0,0,0.45)", color: "#fff", padding: "4px 8px" }}>
            {p.name || p.code} · {new Date(p.uploadedAt).toLocaleDateString()}
          </span>
        </div>
      ))}
    </div>
  );
}

function AdminPortal() {
  const [authed, setAuthed] = useStateA(weddingAPI.isAdmin());
  if (!authed) return <AdminGate onAuth={() => setAuthed(true)} />;
  return <AdminDashboard onLogout={() => setAuthed(false)} />;
}

Object.assign(window, { AdminPortal });
