// web/landing/build-info.jsx — version manifest fetch + Build button + modal.
//
// Role: pulls /version.json (generated by scripts/build-version.sh at deploy
//       time), exposes a tiny <BuildButton/> that displays the version on
//       the nav bar and a <BuildModal/> that pops on click showing channel,
//       commit slug, build time, branch. Designed so remote workers can
//       say "I'm on v.2026.1.47-Dev.5a3c1b9e" without scrolling.
//
// Callers: app.jsx renders <BuildButton/> in <Nav/>. Modal is rendered as
//       a portal-style fixed overlay when open.
//
// Runtime deps: /version.json must be served at the same origin. nginx
//       at infra/qnap/landing/nginx.conf serves the bind-mounted
//       web/landing/ directory which contains version.json after
//       deploy-tunnel.sh / bootstrap-tunnel.sh runs build-version.sh.
//
// Contract: assumes the JSON shape from build-version.sh (version,
//       channel, year, major, minor, slug, branch, commit, built_at).
//       If /version.json 404s, falls back to "v.local" so dev never
//       sees a broken UI.

const VERSION_FALLBACK = {
  version: 'v.local',
  channel: 'unknown',
  year: 0, major: 0, minor: 0,
  slug: 'unknown',
  branch: 'unknown',
  commit: 'unknown',
  built_at: '',
};

function useBuildInfo() {
  const [info, setInfo] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    fetch('/version.json', { cache: 'no-store' })
      .then((r) => (r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`))))
      .then((data) => { if (!cancelled) setInfo({ ...VERSION_FALLBACK, ...data }); })
      .catch(() => { if (!cancelled) setInfo(VERSION_FALLBACK); });
    return () => { cancelled = true; };
  }, []);
  return info;
}

function BuildButton({ onOpen }) {
  const info = useBuildInfo();
  const label = info ? info.version : 'v.…';
  const channel = info ? info.channel : '';
  const channelTint = channel === 'prod' ? '#7fb87f' : channel === 'dev' ? '#d4a574' : '#888';
  return (
    <button
      type="button"
      onClick={onOpen}
      className="ds-btn ds-btn-ghost mono"
      style={{
        fontSize: 11,
        letterSpacing: '0.05em',
        padding: '6px 10px',
        borderColor: `${channelTint}40`,
        color: channelTint,
      }}
      title="Build info"
    >
      <span style={{ marginRight: 6, fontSize: 9, textTransform: 'uppercase', opacity: 0.7 }}>
        {channel || 'build'}
      </span>
      {label}
    </button>
  );
}

function BuildModal({ open, onClose }) {
  const info = useBuildInfo();
  if (!open) return null;
  const rows = info ? [
    ['Version', info.version],
    ['Channel', info.channel],
    ['Branch', info.branch],
    ['Commit', info.commit],
    ['Built',   info.built_at || '—'],
    ['Year',    info.year || '—'],
    ['Major',   info.major],
    ['Minor (tick)', info.minor],
  ] : [['Loading…', '']];

  return (
    <div
      onClick={onClose}
      style={{
        position: 'fixed', inset: 0, zIndex: 1000,
        background: 'rgba(8, 11, 18, 0.85)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 20,
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        className="mono"
        style={{
          background: '#131921',
          border: '1px solid var(--ds-border-bright, rgba(212,165,116,0.4))',
          borderRadius: 8,
          padding: 24,
          minWidth: 380,
          maxWidth: 540,
          color: 'var(--ds-text, #e0d4c2)',
          boxShadow: '0 24px 64px rgba(0,0,0,0.6)',
        }}
      >
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          marginBottom: 16, paddingBottom: 12,
          borderBottom: '1px solid var(--ds-border, rgba(212,165,116,0.1))',
        }}>
          <span style={{ fontSize: 14, fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
            Build manifest
          </span>
          <button
            type="button"
            onClick={onClose}
            style={{
              background: 'transparent', border: 'none', color: 'inherit',
              cursor: 'pointer', fontSize: 18, padding: 4, lineHeight: 1,
            }}
            aria-label="Close"
          >×</button>
        </div>
        <table style={{ width: '100%', fontSize: 12, borderCollapse: 'collapse' }}>
          <tbody>
            {rows.map(([k, v]) => (
              <tr key={k}>
                <td style={{
                  color: 'var(--ds-text-muted, #888)', padding: '6px 12px 6px 0',
                  textTransform: 'uppercase', letterSpacing: '0.05em', fontSize: 10,
                  whiteSpace: 'nowrap', verticalAlign: 'top',
                }}>{k}</td>
                <td style={{
                  padding: '6px 0', wordBreak: 'break-all', fontFamily: 'inherit',
                }}>{String(v)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <div style={{
          marginTop: 16, fontSize: 10, color: 'var(--ds-text-muted, #666)',
          letterSpacing: '0.05em', textTransform: 'uppercase',
        }}>
          Remote workers: include the version above when reporting issues.
        </div>
      </div>
    </div>
  );
}

// Expose for app.jsx (no module system in browser-Babel; rely on globals).
// useBuildInfo is the canonical hook — app.jsx's BuildManifestPopup, hero
// pill, and roadmap "we are here" badge all consume it so the displayed
// version always matches /version.json (regenerated by build-version.sh
// on each deploy). BuildButton + BuildModal are retained as no-op exports
// for any legacy consumer that still references them; the post-redesign
// nav uses the hero pill instead.
window.useBuildInfo = useBuildInfo;
window.BuildButton = BuildButton;
window.BuildModal = BuildModal;
