// RWS — Server browser, Rules
// v1.1: ServersPage now pulls live player counts / queue / map from /api/servers; next-wipe distance is computed.
// v1.2: mobile pass — page paddings/typography scale for ≤768px,
//        ServerRow stacks into a card layout, Leaderboard table gets a
//        horizontal-scroll wrapper, Community channels/staff go from
//        3-/4-col grids to 1-/2-col. Desktop is unchanged.
// v1.3: leaderboards + community pages archived (2026-05-06). Snapshots
//        live at archive/leaderboards-page.jsx and archive/community-page.jsx.
//        Active routes are now home / servers / rules only.

// ─────────────────────────────────────────────
// SERVER BROWSER
// ─────────────────────────────────────────────
const ServersPage = ({ onNav }) => {
  const isMobile = useIsMobile();
  const [filter, setFilter] = useState('all');
  const [sort, setSort] = useState('players');
  const [copied, setCopied] = useState(null);
  const live = useLiveServers();
  const copy = (txt, key) => {
    navigator.clipboard?.writeText(txt);
    setCopied(key);
    setTimeout(() => setCopied(null), 1500);
  };

  // Merge live BattleMetrics data over the static config
  const merged = SERVERS.map(s => mergeLive(s, live));
  const visible = merged.filter(s => filter === 'all' || s.id === filter);

  // Compute next-wipe display from the schedule rule
  const nextWipeDate = getNextWipe();
  const wipeMs = nextWipeDate.getTime() - Date.now();
  const wipeDays = Math.floor(wipeMs / 86400000);
  const wipeHoursMins = formatTimeUntil(nextWipeDate).replace(/^\d+D\s*/, '');

  return (
    <div className="rws tx-canvas art-scroll" style={{ width: '100%', height: '100%' }}>
      <NavBar active="servers" onNav={onNav} />

      <section style={{ padding: isMobile ? '28px 16px 16px' : '48px 60px 24px' }}>
        <div style={{
          display: 'flex',
          flexDirection: isMobile ? 'column' : 'row',
          justifyContent: 'space-between',
          alignItems: isMobile ? 'flex-start' : 'flex-end',
          gap: isMobile ? 20 : 0,
        }}>
          <div>
            <div className="small-caps" style={{ color: 'var(--od-300)' }}>DEPLOYMENT DIRECTORY</div>
            <h1 style={{ fontSize: isMobile ? 36 : 56, margin: '8px 0 0' }}>SERVER BROWSER</h1>
            <p style={{ color: 'var(--od-200)', fontSize: isMobile ? 14 : 15, marginTop: 12, maxWidth: 540 }}>
              Live status pulled every 30 seconds. Click <strong>CONNECT</strong> to copy the join
              command, or <strong>LAUNCH</strong> to fire up Rust and hop straight in.
            </p>
          </div>
          <div style={{
            display: 'flex',
            gap: isMobile ? 24 : 16,
            alignItems: 'center',
            justifyContent: isMobile ? 'flex-start' : 'flex-end',
            flexWrap: 'wrap',
          }}>
            <StatBig label="Online" value={merged.reduce((a, s) => a + (s.players || 0), 0)} align={isMobile ? 'left' : 'right'} />
            <StatBig label="Queued" value={merged.reduce((a, s) => a + (s.queue || 0), 0)} align={isMobile ? 'left' : 'right'} />
            <StatBig label="Next wipe" value={`${wipeDays}D`} sub={wipeHoursMins} align={isMobile ? 'left' : 'right'} />
          </div>
        </div>
      </section>

      {/* Filters */}
      <section style={{
        padding: isMobile ? '12px 16px' : '16px 60px',
        borderTop: '1px solid var(--od-700)',
        borderBottom: '1px solid var(--od-700)',
        background: 'var(--od-800)',
      }}>
        <div style={{
          display: 'flex',
          gap: isMobile ? 14 : 24,
          alignItems: 'center',
          flexWrap: 'wrap',
        }}>
          <FilterGroup label="Group size" value={filter} onChange={setFilter} options={[
            { v: 'all', l: 'All' },
            { v: 'solo', l: 'Solo' },
            { v: 'quad', l: 'Quad' },
          ]} />
          {!isMobile && <div style={{ width: 1, height: 28, background: 'var(--od-600)' }} />}
          <FilterGroup label="Sort by" value={sort} onChange={setSort} options={[
            { v: 'players', l: 'Players' },
            { v: 'wipe', l: 'Wipe date' },
            { v: 'name', l: 'Name' },
          ]} />
          {!isMobile && <div style={{ flex: 1 }} />}
          <div className="mono" style={{ fontSize: 10, color: 'var(--od-300)', letterSpacing: '0.2em' }}>
            AUTO-REFRESH · 30s · LAST {new Date().toLocaleTimeString('en-US', { hour12: false })}
          </div>
        </div>
      </section>

      {/* Server rows */}
      <section style={{ padding: isMobile ? '24px 16px' : '40px 60px' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {visible.map(s => <ServerRow key={s.id} s={s} copied={copied} copy={copy} />)}
        </div>

        <div style={{
          marginTop: 32,
          padding: isMobile ? 20 : 28,
          background: 'var(--od-800)',
          border: '1px solid var(--od-700)',
          display: 'flex',
          flexDirection: isMobile ? 'column' : 'row',
          gap: isMobile ? 14 : 24,
          alignItems: isMobile ? 'flex-start' : 'center',
        }}>
          <div style={{ fontSize: 32, color: 'var(--amber)' }}>ℹ</div>
          <div style={{ flex: 1 }}>
            <div className="stencil" style={{ fontSize: 16, color: 'var(--paper)' }}>FIRST TIME CONNECTING?</div>
            <p style={{ color: 'var(--od-200)', fontSize: 13, margin: '4px 0 0', lineHeight: 1.6 }}>
              Press <kbd style={kbd}>F1</kbd> in Rust to open the console, then paste the connect command.
              Or enable the Steam browser protocol and hit <strong>LAUNCH</strong> above.
            </p>
          </div>
          <button className="btn ghost" style={isMobile ? { width: '100%', justifyContent: 'center' } : {}}>
            How-to guide →
          </button>
        </div>
      </section>

      <SiteFooter onNav={onNav} />
    </div>
  );
};

const kbd = {
  fontFamily: 'var(--f-mono)', fontSize: 11,
  padding: '2px 6px',
  background: 'var(--od-900)', border: '1px solid var(--od-600)',
  borderRadius: 2,
};

function StatBig({ label, value, sub, align = 'right' }) {
  return (
    <div style={{ textAlign: align }}>
      <div className="mono" style={{ fontSize: 9, color: 'var(--od-300)', letterSpacing: '0.2em', textTransform: 'uppercase' }}>{label}</div>
      <div className="stencil" style={{ fontSize: 28, color: 'var(--paper)', lineHeight: 1 }}>{value}</div>
      {sub && <div className="mono" style={{ fontSize: 10, color: 'var(--od-300)' }}>{sub}</div>}
    </div>
  );
}

function FilterGroup({ label, value, onChange, options }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
      <span className="mono" style={{ fontSize: 10, color: 'var(--od-300)', letterSpacing: '0.2em', textTransform: 'uppercase' }}>{label}</span>
      <div style={{ display: 'flex' }}>
        {options.map((o, i) => (
          <button key={o.v} onClick={() => onChange(o.v)}
            className="stencil"
            style={{
              padding: '6px 14px',
              fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase',
              background: value === o.v ? 'var(--blood)' : 'var(--od-700)',
              color: value === o.v ? '#fff' : 'var(--od-200)',
              border: '1px solid var(--od-600)',
              borderLeftWidth: i === 0 ? 1 : 0,
              cursor: 'pointer',
              fontFamily: 'var(--f-stencil)', fontWeight: 600,
            }}>
            {o.l}
          </button>
        ))}
      </div>
    </div>
  );
}

function ServerRow({ s, copied, copy }) {
  const isMobile = useIsMobile();
  const pct = ((s.players || 0) / (s.maxPlayers || 1)) * 100;
  const wipeDistance = formatTimeUntil(getNextWipe());

  // Mobile: stacked card layout. Desktop: 6-column grid.
  if (isMobile) {
    return (
      <div className="card" style={{ padding: 0, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex' }}>
          <div style={{ width: 4, background: s.color, flexShrink: 0 }} />
          <div style={{ padding: '16px 16px', flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', gap: 6, marginBottom: 8, flexWrap: 'wrap' }}>
              <span className="pill live">LIVE</span>
              <span className="pill">{s.gather} GATHER</span>
              <span className="pill">MAX {s.maxGroup}</span>
            </div>
            <div className="stencil" style={{ fontSize: 17, color: 'var(--paper)' }}>{s.name}</div>
            <div className="mono" style={{
              fontSize: 11, color: 'var(--od-300)', marginTop: 4,
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>
              {s.url}
            </div>
            <div className="mono" style={{ fontSize: 10, color: 'var(--od-400)', marginTop: 2 }}>
              {s.ip}
            </div>
          </div>
        </div>

        <div style={{
          display: 'grid',
          gridTemplateColumns: '1fr 1fr',
          gap: 0,
          borderTop: '1px solid var(--od-700)',
        }}>
          <MobileCell label="Players">
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div className="mono" style={{ fontSize: 14, color: 'var(--paper)' }}>
                {s.players}<span style={{ color: 'var(--od-400)' }}>/{s.maxPlayers}</span>
              </div>
              {s.queue > 0 && <span style={{ fontSize: 10, color: 'var(--amber)' }} className="mono">+{s.queue} Q</span>}
            </div>
            <div style={{ width: '100%', height: 3, background: 'var(--od-700)', marginTop: 8 }}>
              <div style={{ width: `${pct}%`, height: '100%', background: s.color }} />
            </div>
          </MobileCell>
          <MobileCell label="Map" borderLeft>
            <div className="mono" style={{ fontSize: 12, color: 'var(--paper)' }}>{s.map}</div>
          </MobileCell>
          <MobileCell label="Next wipe" borderTop>
            <div className="mono" style={{ fontSize: 12, color: 'var(--paper)' }}>{s.nextWipe}</div>
            <div className="mono" style={{ fontSize: 9, color: 'var(--od-300)', marginTop: 4 }}>IN {wipeDistance}</div>
          </MobileCell>
          <MobileCell label="Status" borderLeft borderTop>
            <span className="pill live" style={{ fontSize: 9 }}>ONLINE</span>
          </MobileCell>
        </div>

        <div style={{
          padding: '14px 16px',
          display: 'grid',
          gridTemplateColumns: '1fr 1fr',
          gap: 8,
          borderTop: '1px solid var(--od-700)',
        }}>
          <button className="btn primary" style={{ padding: '11px 14px', fontSize: 11, justifyContent: 'center' }}
            onClick={() => copy(`client.connect ${s.ip}`, s.id)}>
            {copied === s.id ? '✓ COPIED' : 'CONNECT →'}
          </button>
          <button className="btn ghost" style={{ padding: '11px 14px', fontSize: 10, justifyContent: 'center' }}>LAUNCH RUST</button>
        </div>
      </div>
    );
  }

  return (
    <div className="card" style={{ padding: 0, overflow: 'hidden', display: 'grid', gridTemplateColumns: '4px 1.6fr 1fr 1fr 1fr auto', alignItems: 'stretch' }}>
      <div style={{ background: s.color }} />
      <div style={{ padding: '20px 24px' }}>
        <div style={{ display: 'flex', gap: 10, marginBottom: 8 }}>
          <span className="pill live">LIVE</span>
          <span className="pill">{s.gather} GATHER</span>
          <span className="pill">MAX {s.maxGroup}</span>
        </div>
        <div className="stencil" style={{ fontSize: 20, color: 'var(--paper)' }}>{s.name}</div>
        <div className="mono" style={{ fontSize: 11, color: 'var(--od-300)', marginTop: 4 }}>
          {s.url} · {s.ip}
        </div>
      </div>
      <Cell label="Players">
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div className="mono" style={{ fontSize: 15, color: 'var(--paper)' }}>
            {s.players}<span style={{ color: 'var(--od-400)' }}>/{s.maxPlayers}</span>
          </div>
          {s.queue > 0 && <span style={{ fontSize: 10, color: 'var(--amber)' }} className="mono">+{s.queue} Q</span>}
        </div>
        <div style={{ width: '100%', height: 3, background: 'var(--od-700)', marginTop: 8 }}>
          <div style={{ width: `${pct}%`, height: '100%', background: s.color }} />
        </div>
      </Cell>
      <Cell label="Map">
        <div className="mono" style={{ fontSize: 13, color: 'var(--paper)' }}>{s.map}</div>
        <div className="mono" style={{ fontSize: 10, color: 'var(--od-300)', marginTop: 4 }}>SEED 1384720</div>
      </Cell>
      <Cell label="Next wipe">
        <div className="mono" style={{ fontSize: 13, color: 'var(--paper)' }}>{s.nextWipe}</div>
        <div className="mono" style={{ fontSize: 10, color: 'var(--od-300)', marginTop: 4 }}>IN {wipeDistance}</div>
      </Cell>
      <div style={{ padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 6, justifyContent: 'center', borderLeft: '1px solid var(--od-700)' }}>
        <button className="btn primary" style={{ padding: '10px 18px', fontSize: 11 }}
          onClick={() => copy(`client.connect ${s.ip}`, s.id)}>
          {copied === s.id ? '✓ COPIED' : 'CONNECT →'}
        </button>
        <button className="btn ghost" style={{ padding: '6px 12px', fontSize: 10, justifyContent: 'center' }}>LAUNCH RUST</button>
      </div>
    </div>
  );
}

function Cell({ label, children }) {
  return (
    <div style={{ padding: '20px 20px', borderLeft: '1px solid var(--od-700)', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
      <div className="mono" style={{ fontSize: 9, color: 'var(--od-300)', letterSpacing: '0.2em', textTransform: 'uppercase', marginBottom: 6 }}>{label}</div>
      {children}
    </div>
  );
}

function MobileCell({ label, children, borderLeft, borderTop }) {
  return (
    <div style={{
      padding: '12px 14px',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      borderLeft: borderLeft ? '1px solid var(--od-700)' : 'none',
      borderTop: borderTop ? '1px solid var(--od-700)' : 'none',
    }}>
      <div className="mono" style={{ fontSize: 9, color: 'var(--od-300)', letterSpacing: '0.2em', textTransform: 'uppercase', marginBottom: 6 }}>{label}</div>
      {children}
    </div>
  );
}

// ─────────────────────────────────────────────
// RULES
// ─────────────────────────────────────────────
const RulesPage = ({ onNav }) => {
  const isMobile = useIsMobile();
  const [open, setOpen] = useState(null);

  return (
    <div className="rws tx-canvas art-scroll" style={{ width: '100%', height: '100%' }}>
      <NavBar active="rules" onNav={onNav} />

      <section style={{ padding: isMobile ? '28px 16px 16px' : '48px 60px 32px' }}>
        <div className="small-caps" style={{ color: 'var(--od-300)' }}>STANDING ORDERS · UPDATED 02 APR 2026</div>
        <h1 style={{ fontSize: isMobile ? 34 : 56, margin: '8px 0 0' }}>RULES OF ENGAGEMENT</h1>
        <p style={{ color: 'var(--od-200)', fontSize: isMobile ? 14 : 15, marginTop: 16, maxWidth: 660, lineHeight: 1.6 }}>
          Nine rules. That's it. We'd love fewer, but people keep finding new ways to ruin things.
          If something's unclear, ask in <strong>#ask-staff</strong> on Discord — we'd rather answer
          a question than issue a ban.
        </p>
      </section>

      <section style={{ padding: isMobile ? '12px 16px 36px' : '24px 60px 56px' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {RULES.map((r, i) => {
            const isOpen = open === i;
            return (
              <div key={i} className="stencil-frame" style={{ overflow: 'hidden', transition: 'all 0.2s' }}>
                <button onClick={() => setOpen(isOpen ? null : i)} style={{
                  width: '100%',
                  padding: isMobile ? '16px 16px' : '20px 24px',
                  background: 'transparent', border: 0,
                  display: 'grid',
                  gridTemplateColumns: isMobile ? '40px 1fr 18px' : '60px 1fr auto auto',
                  alignItems: 'center',
                  gap: isMobile ? 12 : 20,
                  cursor: 'pointer', textAlign: 'left',
                }}>
                  <div className="stencil" style={{
                    fontSize: isMobile ? 24 : 32,
                    color: isOpen ? 'var(--blood-hot)' : 'var(--od-400)',
                    lineHeight: 1,
                  }}>{r.cat}</div>
                  <div style={{ minWidth: 0 }}>
                    <div className="stencil" style={{ fontSize: isMobile ? 15 : 18, color: 'var(--paper)' }}>{r.title}</div>
                    {!isOpen && (
                      <div style={{
                        color: 'var(--od-300)',
                        fontSize: isMobile ? 12 : 13,
                        marginTop: 4,
                        maxWidth: 520,
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                        whiteSpace: 'nowrap',
                      }}>
                        {r.body}
                      </div>
                    )}
                    {isMobile && (
                      <div style={{ marginTop: 8 }}>
                        <span className="pill bad" style={{ fontSize: 9 }}>{r.severity}</span>
                      </div>
                    )}
                  </div>
                  {!isMobile && <span className="pill bad" style={{ fontSize: 9 }}>{r.severity}</span>}
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"
                    style={{ color: 'var(--od-300)', transform: isOpen ? 'rotate(180deg)' : 'rotate(0)', transition: 'transform 0.2s', justifySelf: 'end' }}>
                    <path d="M6 9l6 6 6-6" />
                  </svg>
                </button>
                {isOpen && (
                  <div style={{
                    padding: isMobile ? '0 16px 18px 16px' : '0 24px 24px 104px',
                    borderTop: '1px dashed var(--od-600)',
                  }}>
                    <p style={{ color: 'var(--od-200)', fontSize: 14, lineHeight: 1.7, margin: '16px 0 0' }}>
                      {r.body}
                    </p>
                  </div>
                )}
              </div>
            );
          })}
        </div>

        <div className="stencil-frame" style={{
          marginTop: 28,
          padding: isMobile ? 18 : 24,
          display: 'flex',
          flexDirection: isMobile ? 'column' : 'row',
          gap: isMobile ? 14 : 20,
          alignItems: isMobile ? 'flex-start' : 'center',
        }}>
          <div className="stamp" style={{ transform: 'rotate(-4deg)', flexShrink: 0 }}>APPEAL</div>
          <div style={{ flex: 1 }}>
            <div className="stencil" style={{ fontSize: 16, color: 'var(--paper)' }}>GOT BANNED? DISAGREE?</div>
            <p style={{ color: 'var(--od-200)', fontSize: 13, margin: '4px 0 0', lineHeight: 1.6 }}>
              File an appeal in <strong>#ban-appeals</strong> on Discord. Include your Steam ID,
              the server, and what you think happened. We review every single one.
            </p>
          </div>
          <button className="btn" style={isMobile ? { width: '100%', justifyContent: 'center' } : {}}>File appeal →</button>
        </div>
      </section>

      <SiteFooter onNav={onNav} />
    </div>
  );
};

function RulesSummary({ label, value, delta }) {
  return (
    <div className="card" style={{ padding: 20 }}>
      <div className="mono" style={{ fontSize: 10, color: 'var(--od-300)', letterSpacing: '0.2em', textTransform: 'uppercase' }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginTop: 6 }}>
        <div className="stencil" style={{ fontSize: 32, color: 'var(--paper)', lineHeight: 1 }}>{value}</div>
        <div className="mono" style={{ fontSize: 11, color: 'var(--ok)' }}>{delta}</div>
      </div>
    </div>
  );
}

// LEADERBOARDS + COMMUNITY pages archived 2026-05-06.
// See archive/leaderboards-page.jsx and archive/community-page.jsx.

Object.assign(window, { ServersPage, RulesPage });
