// admin-applications.jsx — Applications list + detail (notes, activity, status, edit).

function AppsList({ session, onOpen, apps: initialApps }) {
  const [apps, setApps] = React.useState(initialApps || []);
  const [users, setUsers] = React.useState([]);
  const [filter, setFilter] = React.useState('all');
  const [q, setQ] = React.useState('');
  const [sortKey, setSortKey] = React.useState('created_at');
  const [sortDir, setSortDir] = React.useState('desc');

  React.useEffect(() => {
    if (initialApps !== undefined) {
      setApps(initialApps);
    } else {
      ATS.loadApplications().then(setApps);
    }
    ATS.loadUsers().then(setUsers).catch(() => {});
  }, []);

  const counts = {
    all: apps.length,
    pending: apps.filter((a) => a.status === 'pending').length,
    approved: apps.filter((a) => a.status === 'approved').length,
    rejected: apps.filter((a) => a.status === 'rejected').length,
    withdrawn: apps.filter((a) => a.status === 'withdrawn').length
  };

  const filtered = React.useMemo(() => {
    let list = apps;
    if (filter !== 'all') list = list.filter((a) => a.status === filter);
    if (q.trim()) {
      const needle = q.trim().toLowerCase();
      list = list.filter((a) =>
        (a.player_name || '').toLowerCase().includes(needle) ||
        String(a.state_number).includes(needle) ||
        (a.alliance_name || '').toLowerCase().includes(needle) ||
        (a.discord_username || '').toLowerCase().includes(needle)
      );
    }
    list = list.slice().sort((x, y) => {
      const dir = sortDir === 'asc' ? 1 : -1;
      const a = x[sortKey], b = y[sortKey];
      if (typeof a === 'number' && typeof b === 'number') return (a - b) * dir;
      return String(a || '').localeCompare(String(b || '')) * dir;
    });
    return list;
  }, [apps, filter, q, sortKey, sortDir]);

  const toggleSort = (k) => {
    if (sortKey === k) setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
    else { setSortKey(k); setSortDir('desc'); }
  };
  const sortIcon = (k) => sortKey !== k ? '' : sortDir === 'asc' ? ' ↑' : ' ↓';

  return (
    <>
      <StatStrip>
        <StatCard lbl="Total applications" val={apps.length} />
        <StatCard lbl="Pending review" val={counts.pending} color="#fbbf24" />
        <StatCard lbl="Approved" val={counts.approved} color="#5eead4" />
        <StatCard lbl="Rejected" val={counts.rejected} color="#f87171" />
      </StatStrip>

      <div className="apps-toolbar">
        <div className="filters">
          {[
            ['all', 'All'], ['pending', 'Pending'], ['approved', 'Approved'],
            ['rejected', 'Rejected'], ['withdrawn', 'Withdrawn'],
          ].map(([v, l]) =>
            <button key={v} className={filter === v ? 'on' : ''} onClick={() => setFilter(v)}>
              {l} <span className="ct">{counts[v]}</span>
            </button>
          )}
        </div>
        <div className="search-wrap">
          <ADMIN_ICONS.search width="14" height="14" />
          <input value={q} onChange={(e) => setQ(e.target.value)}
            placeholder="Search name, state, alliance, discord…" />
        </div>
      </div>

      <div className="apps-tbl">
        <div className="apps-scroll">
          <div className="apps-row head">
            <div onClick={() => toggleSort('created_at')} role="button">Date{sortIcon('created_at')}</div>
            <div onClick={() => toggleSort('player_name')} role="button">Player{sortIcon('player_name')}</div>
            <div onClick={() => toggleSort('state_number')} role="button">State{sortIcon('state_number')}</div>
            <div onClick={() => toggleSort('furnace_level')} role="button">Furnace{sortIcon('furnace_level')}</div>
            <div onClick={() => toggleSort('power_level')} role="button">Power{sortIcon('power_level')}</div>
            <div>Alliance</div>
            <div onClick={() => toggleSort('status')} role="button">Status{sortIcon('status')}</div>
            <div style={{ textAlign: 'right' }}>Actions</div>
          </div>
          {filtered.length === 0 &&
            <div className="apps-empty">
              <h3>No applications match.</h3>
              <p>Adjust your filter or search to see more.</p>
            </div>
          }
          {filtered.map((a) =>
            <div key={a.id} className="apps-row" onClick={() => onOpen(a.id)}>
              <div className="apps-cell apps-date">
                {ATS.fmtAgo(a.created_at)}
                <small>{ATS.fmtDate(a.created_at)}</small>
              </div>
              <div className="apps-cell apps-name">
                {a.player_name}
                <small>{a.discord_username || human_username || '—'}</small>
              </div>
              <div className="apps-cell"><b>{a.state_number}</b></div>
              <div className="apps-cell"><b>{a.furnace_level}</b></div>
              <div className="apps-cell"><b>{a.power_level}</b></div>
              <div className="apps-cell">{a.alliance_name || '—'}{a.alliance_rank ? ' · ' + a.alliance_rank : ''}</div>
              <div><span className={'app-status ' + a.status}>{a.status}</span></div>
              <div className="apps-actions">
                <button className="btn btn-ghost btn-sm view-btn"
                  onClick={(e) => { e.stopPropagation(); onOpen(a.id); }}>
                  <ADMIN_ICONS.eye width="13" height="13" /> View
                </button>
              </div>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// ── Detail view ────────────────────────────────────────────
function AppDetail({ id, session, onBack }) {
  const [app, setApp] = React.useState(null);
  const [appNotes, setAppNotes] = React.useState([]);
  const [appActivity, setAppActivity] = React.useState([]);
  const [users, setUsers] = React.useState([]);
  const [alliances, setAlliances] = React.useState([]);
  const [newNote, setNewNote] = React.useState('');
  const [confirmDel, setConfirmDel] = React.useState(false);
  const [showActivity, setShowActivity] = React.useState(true);
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft] = React.useState(null);

  React.useEffect(() => {
    if (!id) return;
    const load = async () => {
      const apps = await ATS.loadApplications();
      const thisApp = apps.find((a) => a.id === id);
      if (thisApp) {
        // Also load additional players and notes
        try {
          const detailRes = await fetch(`/api/applications/${id}`, { credentials: 'include' });
          if (detailRes.ok) {
            const detail = await detailRes.json();
            thisApp.additional_players = detail.additional_players || [];
          }
        } catch {}
        setApp(thisApp);
      }
      const [u, al] = await Promise.all([
        ATS.loadUsers().catch(() => []),
        ATS.loadAlliances().catch(() => []),
      ]);
      setUsers(u);
      setAlliances(al);
    };
    const loadNotesActivity = async () => {
      try {
        const [notesRes, activityRes] = await Promise.all([
          fetch(`/api/applications/${id}/notes`, { credentials: 'include' }),
          fetch(`/api/applications/${id}/activity`, { credentials: 'include' }),
        ]);
        if (notesRes.ok) setAppNotes(await notesRes.json());
        if (activityRes.ok) setAppActivity(await activityRes.json());
      } catch {}
    };
    load();
    loadNotesActivity();
  }, [id]);

  if (!app) {
    return (
      <div className="admin-content">
        <div className="empty">
          <h3>Loading…</h3>
        </div>
      </div>
    );
  }

  const userName = (uid) => uid ? users.find((u) => u.id === uid)?.name || 'Unknown' : 'System';
  const prefAlliance = app.preferred_alliance_id ? alliances.find((x) => x.id === app.preferred_alliance_id) : null;

  const setStatus = async (status) => {
    await ATS.updateApplication(id, { status }, session?.id);
    const apps = await ATS.loadApplications();
    const updated = apps.find((a) => a.id === id);
    if (updated) setApp(updated);
  };

  const canEdit = session && ATS.roleAtLeast(session.role, 'admin');
  const startEdit = () => {
    setDraft({
      player_name: app.player_name || '',
      state_number: app.state_number ?? '',
      furnace_level: app.furnace_level ?? '',
      power_level: app.power_level ?? '',
      alliance_name: app.alliance_name || '',
      alliance_rank: app.alliance_rank || '',
      x_coordinate: app.x_coordinate ?? '',
      y_coordinate: app.y_coordinate ?? '',
      discord_username: app.discord_username || '',
      language: app.language || 'en',
    });
    setEditing(true);
  };
  const cancelEdit = () => { setEditing(false); setDraft(null); };
  const saveEdit = async () => {
    const toNum = (v) => v === '' || v == null ? null : Number.isFinite(+v) ? +v : v;
    const patch = {
      player_name: draft.player_name.trim(),
      state_number: toNum(draft.state_number),
      furnace_level: draft.furnace_level,
      power_level: String(draft.power_level).trim(),
      alliance_name: draft.alliance_name.trim() || null,
      alliance_rank: draft.alliance_rank || null,
      x_coordinate: toNum(draft.x_coordinate),
      y_coordinate: toNum(draft.y_coordinate),
      discord_username: draft.discord_username.trim() || null,
      language: draft.language,
    };
    await ATS.updateApplication(id, patch, session?.id);
    setApp((prev) => ({ ...prev, ...patch }));
    setEditing(false);
    setDraft(null);
  };
  const setField = (k, v) => setDraft((d) => ({ ...d, [k]: v }));
  const addNote = async (e) => {
    e.preventDefault();
    if (!newNote.trim()) return;
    await ATS.addNote(id, session?.id || null, newNote.trim());
    setNewNote('');
    const notesRes = await fetch(`/api/applications/${id}/notes`, { credentials: 'include' });
    if (notesRes.ok) setAppNotes(await notesRes.json());
  };
  const remove = async () => {
    await ATS.deleteApplication(id);
    onBack();
  };

  const appNotesSorted = [...appNotes].sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
  const appActivitySorted = [...appActivity].sort((a, b) => new Date(b.created_at) - new Date(a.created_at));

  const stageStyle = { background: 'rgba(0,0,0,0.18)', border: '1px solid var(--border)', borderRadius: 12, padding: 14 };

  return (
    <>
      <div className="detail-back-row">
        <button className="btn btn-ghost btn-sm" onClick={onBack}>
          <ADMIN_ICONS.back width="13" height="13" /> All applications
        </button>
        <button className="btn btn-ghost btn-sm" style={{ marginLeft: 'auto', color: '#fca5a5', borderColor: 'rgba(248,113,113,0.3)' }}
          onClick={() => setConfirmDel(true)}>
          <ADMIN_ICONS.trash width="13" height="13" /> Delete application
        </button>
      </div>

      <div className="detail-grid">
        {/* Left column */}
        <div className="admin-content">
          <div className="panel-head">
            <div className="titlewrap">
              <div className="mark">{app.player_name.slice(0, 2).toUpperCase()}</div>
              <div style={{ minWidth: 0, flex: 1 }}>
                <h2>{app.player_name}</h2>
                <div className="sub">
                  <span>State <b>{app.state_number}</b></span>
                  <span>Furnace <b>{app.furnace_level}</b></span>
                  <span>Power <b>{app.power_level}</b></span>
                  <span><span className={'app-status ' + app.status}>{app.status}</span></span>
                </div>
              </div>
            </div>
          </div>

          <div className="panel-body">
            <div className="panel-section">
              <div className="panel-section-head">
                <h3>Player info</h3>
                {canEdit && !editing &&
                  <button className="btn btn-ghost btn-sm" onClick={startEdit}>
                    <ADMIN_ICONS.edit width="13" height="13" /> Edit
                  </button>
                }
                {editing &&
                  <div style={{ display: 'flex', gap: 8 }}>
                    <button className="btn btn-ghost btn-sm" onClick={cancelEdit}>Cancel</button>
                    <button className="btn btn-primary btn-sm" onClick={saveEdit}>Save changes</button>
                  </div>
                }
              </div>
              {!editing &&
                <div className="detail-grid-2">
                  <KV label="Player name" v={app.player_name} />
                  <KV label="State number" v={app.state_number} />
                  <KV label="Furnace level" v={app.furnace_level} />
                  <KV label="Power level" v={app.power_level} />
                  <KV label="Current alliance" v={app.alliance_name || '—'} />
                  <KV label="Alliance rank" v={app.alliance_rank || '—'} />
                  <KV label="Coordinates" v={app.x_coordinate != null && app.y_coordinate != null ? `${app.x_coordinate}, ${app.y_coordinate}` : '—'} />
                  <KV label="Discord" v={app.discord_username || '—'} />
                  <KV label="Language" v={(ATS.LANGUAGES.find((l) => l.code === app.language) || {}).label || app.language} />
                  <KV label="Preferred alliance" v={prefAlliance ? prefAlliance.name : '—'} />
                </div>
              }
              {editing && draft &&
                <div className="detail-grid-2">
                  <div className="field"><label>Player name</label>
                    <input value={draft.player_name} onChange={(e) => setField('player_name', e.target.value)} /></div>
                  <div className="field"><label>State number</label>
                    <input type="number" value={draft.state_number} onChange={(e) => setField('state_number', e.target.value)} /></div>
                  <div className="field"><label>Furnace level</label>
                    <select value={draft.furnace_level} onChange={(e) => setField('furnace_level', e.target.value)}>
                      <option value="">Select…</option>
                      {ATS.FURNACE_LEVELS.map((f) => <option key={f} value={f}>{f}</option>)}
                    </select></div>
                  <div className="field"><label>Power level</label>
                    <input value={draft.power_level} onChange={(e) => setField('power_level', e.target.value)} placeholder="e.g. 12M" /></div>
                  <div className="field"><label>Current alliance</label>
                    <input value={draft.alliance_name} onChange={(e) => setField('alliance_name', e.target.value)} /></div>
                  <div className="field"><label>Alliance rank</label>
                    <select value={draft.alliance_rank} onChange={(e) => setField('alliance_rank', e.target.value)}>
                      <option value="">—</option>
                      {ATS.ALLIANCE_RANKS.map((r) => <option key={r} value={r}>{r}</option>)}
                    </select></div>
                  <div className="field"><label>X coordinate</label>
                    <input type="number" value={draft.x_coordinate} onChange={(e) => setField('x_coordinate', e.target.value)} /></div>
                  <div className="field"><label>Y coordinate</label>
                    <input type="number" value={draft.y_coordinate} onChange={(e) => setField('y_coordinate', e.target.value)} /></div>
                  <div className="field"><label>Discord</label>
                    <input value={draft.discord_username} onChange={(e) => setField('discord_username', e.target.value)} placeholder="@kaiserbolt" /></div>
                  <div className="field"><label>Language</label>
                    <select value={draft.language} onChange={(e) => setField('language', e.target.value)}>
                      {ATS.LANGUAGES.map((l) => <option key={l.code} value={l.code}>{l.label}</option>)}
                    </select></div>
                  <div className="field" style={{ gridColumn: '1 / -1' }}><label>Preferred alliance</label>
                    <select value={draft.preferred_alliance_id || ''} onChange={(e) => setField('preferred_alliance_id', e.target.value)}>
                      <option value="">— No preference —</option>
                      {alliances.map((al) => <option key={al.id} value={al.id}>{al.name}</option>)}
                    </select></div>
                </div>
              }
              {!editing && app.notes &&
                <div style={{ ...stageStyle, marginTop: 18 }}>
                  <div className="kv-lbl" style={{ marginBottom: 6 }}>Applicant notes</div>
                  <div style={{ color: 'var(--text-dim)', fontSize: '0.92rem', lineHeight: 1.5, whiteSpace: 'pre-wrap' }}>{app.notes}</div>
                </div>
              }
            </div>

            {/* Additional players */}
            {app.additional_players && app.additional_players.length > 0 &&
              <div className="panel-section">
                <h3>Additional players ({app.additional_players.length})</h3>
                <div className="addp-list">
                  {app.additional_players.map((p, i) =>
                    <div key={i} className="addp-grid">
                      <div className="addp-grid-h">Player {i + 2}: <b>{p.player_name}</b></div>
                      <div className="addp-grid-row">
                        <KV label="Furnace" v={p.furnace_level} />
                        <KV label="Power" v={p.power_level} />
                        <KV label="Coords" v={p.x_coordinate != null ? `${p.x_coordinate}, ${p.y_coordinate}` : '—'} />
                      </div>
                    </div>
                  )}
                </div>
              </div>
            }

            {/* Activity log */}
            <div className="panel-section">
              <button className="panel-toggle" onClick={() => setShowActivity(!showActivity)}>
                <ADMIN_ICONS.chev width="14" height="14" style={{ transform: showActivity ? 'rotate(90deg)' : 'rotate(0deg)', transition: 'transform .15s' }} />
                Activity log ({appActivitySorted.length})
              </button>
              {showActivity &&
                <div className="activity-list">
                  {appActivitySorted.length === 0 && <div style={{ color: 'var(--text-faint)', fontSize: '0.88rem' }}>No activity yet.</div>}
                  {appActivitySorted.map((a) =>
                    <div key={a.id} className="activity-row">
                      <div className="activity-dot" data-action={a.action} />
                      <div className="activity-body">
                        <div className="activity-h">
                          <span className="activity-action">{a.action.replace('_', ' ')}</span>
                          <span className="activity-user">by {userName(a.user_id)}</span>
                          <span className="activity-when">{ATS.fmtAgo(a.created_at)}</span>
                        </div>
                        {a.details && <div className="activity-details">{a.details}</div>}
                      </div>
                    </div>
                  )}
                </div>
              }
            </div>
          </div>
        </div>

        {/* Right column — status + notes */}
        <div className="detail-side">
          <div className="admin-content side-card">
            <div className="side-head">Status</div>
            <div className="side-body">
              <div className="status-stack">
                {ATS.APPLICATION_STATUS.map((s) =>
                  <button key={s}
                    className={'status-opt ' + s + (app.status === s ? ' on' : '')}
                    onClick={() => setStatus(s)}>
                    {app.status === s && <ADMIN_ICONS.check width="14" height="14" />}
                    {s}
                  </button>
                )}
              </div>
              <div className="status-meta">
                <div><span>Created</span><b>{ATS.fmtDate(app.created_at)}</b></div>
                <div><span>Updated</span><b>{ATS.fmtDate(app.updated_at)}</b></div>
              </div>
            </div>
          </div>

          <div className="admin-content side-card">
            <div className="side-head">Notes thread ({appNotesSorted.length})</div>
            <div className="side-body">
              <div className="notes-thread">
                {appNotesSorted.length === 0 && <div style={{ color: 'var(--text-faint)', fontSize: '0.85rem', padding: 8 }}>No notes yet — start the thread below.</div>}
                {appNotesSorted.map((n) =>
                  <div key={n.id} className="note-row">
                    <div className="note-head">
                      <span className="note-author">{userName(n.user_id)}</span>
                      <span className="note-when">{ATS.fmtAgo(n.created_at)}</span>
                    </div>
                    <div className="note-body">{n.note}</div>
                  </div>
                )}
              </div>
              <form className="note-form" onSubmit={addNote}>
                <textarea value={newNote} onChange={(e) => setNewNote(e.target.value)}
                  placeholder="Add a note for other officers…" rows={3} />
                <button type="submit" className="btn btn-primary btn-sm" disabled={!newNote.trim()}>
                  Post note
                </button>
              </form>
            </div>
          </div>
        </div>
      </div>

      <Confirm open={confirmDel}
        title="Delete application?"
        confirmText="Delete"
        danger
        onConfirm={remove}
        onClose={() => setConfirmDel(false)}>
        <p>Permanently removes {app.player_name} from the queue, along with all notes and activity. Can't be undone.</p>
      </Confirm>
    </>
  );
}

function KV({ label, v }) {
  return (
    <div className="kv">
      <div className="kv-lbl">{label}</div>
      <div className="kv-v">{v}</div>
    </div>
  );
}

// ── Wrapper: list ↔ detail ─────────────────────────────────
function ApplicationsView({ session, apps }) {
  const [detailId, setDetailId] = React.useState(null);
  if (detailId != null) {
    return <AppDetail id={detailId} session={session} onBack={() => setDetailId(null)} />;
  }
  return <AppsList session={session} onOpen={setDetailId} apps={apps} />;
}

Object.assign(window, { AppsList, AppDetail, ApplicationsView, KV });