// components.jsx — shared UI primitives: Logo, BottomNav, QRCode, QRScanner, helpers.

const { useState: cU, useEffect: cE, useRef: cR, useMemo: cM } = React;

function Brand({ size = 22, onClick }) {
  return (
    <a
      href="/"
      onClick={(e) => { if (onClick) { e.preventDefault(); onClick(); } }}
      className="brand"
      style={{ fontSize: size }}
    >
      <span className="brand-mark">Poker</span>{' '}Jamie
    </a>
  );
}

function TopBar({ onNav, current }) {
  return (
    <div className="topbar">
      <Brand onClick={() => onNav('/')} />
      <div className="row" style={{ gap: 10 }}>
        <span className="tag tag-gold">BETA</span>
      </div>
    </div>
  );
}

function BottomNav({ current, onNav }) {
  const items = [
    { key: 'home',   path: '/',      glyph: '♠', label: 'Home' },
    { key: 'new',    path: '/new',   glyph: '+', label: 'New' },
    { key: 'swaps',  path: '/swaps', glyph: '◆', label: 'Swaps' },
    { key: 'teams',  path: '/teams', glyph: '♣', label: 'Boys' },
    { key: 'reg',    path: '/reg',   glyph: '♦', label: 'Late Reg' }
  ];
  return (
    <nav className="bottomnav">
      {items.map(it => (
        <button
          key={it.key}
          className={'bottomnav-item' + (current === it.key ? ' on' : '')}
          onClick={() => onNav(it.path)}
        >
          <span className="bottomnav-glyph">{it.glyph}</span>
          {it.label}
        </button>
      ))}
    </nav>
  );
}

// ---- QRCode (image element rendered from text) -----------------------------
function QRCodeBlock({ text, size = 280, caption = 'SCAN TO LOCK' }) {
  const [dataUrl, setDataUrl] = cU(null);
  const [err, setErr] = cU(null);
  cE(() => {
    let cancelled = false;
    if (!text) return;
    if (!window.QRCode || !window.QRCode.toDataURL) {
      setErr('QR library failed to load');
      return;
    }
    window.QRCode.toDataURL(text, {
      errorCorrectionLevel: 'H',
      margin: 1,
      width: size,
      color: { dark: '#0a0a0b', light: '#ffffff' }
    }).then(url => { if (!cancelled) setDataUrl(url); })
      .catch(e => { if (!cancelled) setErr(String(e)); });
    return () => { cancelled = true; };
  }, [text, size]);

  return (
    <div className="qr-frame">
      <div className="qr-wrap" style={{ minHeight: size }}>
        {dataUrl
          ? <img src={dataUrl} width={size} height={size} alt="Lock QR code" style={{ display: 'block' }} />
          : err
            ? <span className="mono" style={{ color: 'var(--red-bright)', fontSize: 12 }}>{err}</span>
            : <span className="mono" style={{ color: 'var(--muted)', fontSize: 12 }}>Generating QR…</span>}
      </div>
      <div className="qr-caption">{caption}</div>
    </div>
  );
}

// ---- QRScanner (uses html5-qrcode) -----------------------------------------
function QRScanner({ onResult, onCancel }) {
  const divId = cM(() => 'qrreader-' + Math.random().toString(36).slice(2, 8), []);
  const scannerRef = cR(null);
  const [err, setErr] = cU(null);

  cE(() => {
    let active = true;
    if (!window.Html5Qrcode) {
      setErr('Scanner library failed to load. Paste link instead.');
      return;
    }
    const inst = new window.Html5Qrcode(divId);
    scannerRef.current = inst;
    inst.start(
      { facingMode: 'environment' },
      { fps: 10, qrbox: { width: 240, height: 240 } },
      (decoded) => {
        if (!active) return;
        active = false;
        inst.stop().then(() => inst.clear()).catch(() => {});
        onResult(decoded);
      },
      () => { /* ignore per-frame errors */ }
    ).catch(e => setErr(String(e && e.message || e)));

    return () => {
      active = false;
      try {
        const s = scannerRef.current;
        if (s) s.stop().then(() => s.clear()).catch(() => {});
      } catch (_) {}
    };
  }, []);

  return (
    <div className="card" style={{ padding: 14 }}>
      <div id={divId} style={{ width: '100%', maxWidth: 360, margin: '0 auto' }} />
      {err && <p className="mono" style={{ color: 'var(--red-bright)', fontSize: 12, marginTop: 12 }}>{err}</p>}
      <div className="row" style={{ marginTop: 14, justifyContent: 'flex-end' }}>
        <button className="btn btn-ghost" onClick={onCancel}>Cancel</button>
      </div>
    </div>
  );
}

// ---- Small util components -------------------------------------------------
function Field({ label, children, help }) {
  return (
    <div className="field">
      <label className="label">{label}</label>
      {children}
      {help && <div className="help">{help}</div>}
    </div>
  );
}

function Chip({ on, onClick, children }) {
  return (
    <button
      type="button"
      className={'chip' + (on ? ' chip-on' : '')}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

function StatRow({ label, value, mono }) {
  return (
    <div className="row-between" style={{ padding: '10px 0', borderBottom: '1px solid var(--line)' }}>
      <span className="mono" style={{ fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--muted)' }}>{label}</span>
      <span className={mono ? 'num' : ''} style={{ fontSize: 15, color: 'var(--ivory)', textAlign: 'right' }}>{value}</span>
    </div>
  );
}

function Footer() {
  return (
    <div className="footer">
      <p>
        Poker Jamie records agreements between consenting adults. Disputes are between
        the players. Not affiliated with the WSOP, Caesars Entertainment, or Jamie Gold.
      </p>
      <p>
        Don't get Jamied. <span style={{ color: 'var(--gold)' }}>Lock it in.</span>
      </p>
    </div>
  );
}

// ---- Format helpers --------------------------------------------------------
function fmtMoney(n) {
  const v = Number(n) || 0;
  return '$' + v.toLocaleString('en-US', { maximumFractionDigits: 0 });
}
function fmtPct(n) {
  return (Number(n) || 0).toFixed(0) + '%';
}
function fmtDateTime(iso) {
  if (!iso) return '—';
  try {
    const d = new Date(iso);
    return d.toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
  } catch (_) { return iso; }
}
function fmtCountdown(iso) {
  if (!iso) return '—';
  const ms = new Date(iso).getTime() - Date.now();
  if (ms <= 0) return 'CLOSED';
  const mins = Math.floor(ms / 60000);
  if (mins < 60) return mins + 'm';
  const hrs = Math.floor(mins / 60);
  if (hrs < 48) return hrs + 'h ' + (mins % 60) + 'm';
  const days = Math.floor(hrs / 24);
  return days + 'd ' + (hrs % 24) + 'h';
}

window.PJ_UI = {
  Brand, TopBar, BottomNav, QRCodeBlock, QRScanner,
  Field, Chip, StatRow, Footer,
  fmtMoney, fmtPct, fmtDateTime, fmtCountdown
};
