// Shared UI primitives for Remnant Reporting
// Colors/fonts flow from tokens.css — keep literal values matching.

const REM = {
  obsidian: '#1A1A1A',
  linen:    '#F0EEEA',
  abyss:    '#0A2C2C',
  deepTeal: '#0D5C5C',
  forest:   '#1A7A6E',
  teal:     '#2EA896',
  sage:     '#5BC8B8',
  inkMuted: '#4A4A4A',
  inkSubtle:'#7A7A7A',
  fontDisplay: "'Space Grotesk', ui-sans-serif, system-ui, sans-serif",
  fontSub:     "'Archivo', ui-sans-serif, system-ui, sans-serif",
  fontBody:    "'Manrope', ui-sans-serif, system-ui, sans-serif",
};

// Tiny click sound (WebAudio, no asset)
const Haptic = (() => {
  let ctx = null;
  let enabled = true;
  function get() { if (!ctx) ctx = new (window.AudioContext || window.webkitAudioContext)(); return ctx; }
  return {
    tick(freq = 1400) {
      if (!enabled) return;
      try {
        const ac = get();
        const osc = ac.createOscillator(); const g = ac.createGain();
        osc.frequency.value = freq; osc.type = 'square';
        g.gain.value = 0; osc.connect(g).connect(ac.destination);
        const t = ac.currentTime;
        g.gain.setValueAtTime(0, t);
        g.gain.linearRampToValueAtTime(0.035, t + 0.003);
        g.gain.exponentialRampToValueAtTime(0.0001, t + 0.06);
        osc.start(t); osc.stop(t + 0.07);
      } catch(e) {}
      if (navigator.vibrate) navigator.vibrate(8);
    },
    thud() { this.tick(420); },
    setEnabled(v) { enabled = v; }
  };
})();

// Wordmark — REMNANT. with sage period
function Wordmark({ color = REM.obsidian, period = REM.sage, size = 14, tracking = '-0.035em', weight = 600 }) {
  return (
    <span style={{
      fontFamily: REM.fontDisplay, fontWeight: weight, letterSpacing: tracking,
      textTransform: 'uppercase', color, fontSize: size, lineHeight: 1, display: 'inline-flex', alignItems: 'baseline',
    }}>
      REMNANT<span style={{ color: period }}>.</span>
    </span>
  );
}

// Eyebrow label — tracked uppercase Archivo
function Eyebrow({ children, color = REM.inkSubtle, size = 10, track = '0.2em', style = {} }) {
  return (
    <span style={{
      fontFamily: REM.fontSub, fontWeight: 700, fontSize: size, letterSpacing: track,
      textTransform: 'uppercase', color, lineHeight: 1, ...style,
    }}>{children}</span>
  );
}

// Hairline rule
function Rule({ color, vertical = false, style = {} }) {
  const c = color || 'rgba(26,26,26,.12)';
  if (vertical) return <div style={{ width: 1, background: c, alignSelf: 'stretch', ...style }} />;
  return <div style={{ height: 1, background: c, width: '100%', ...style }} />;
}

// Press: subtle scale + optional haptic
function Press({ onClick, children, style = {}, haptic = true, freq = 1400, ...rest }) {
  const [down, setDown] = React.useState(false);
  return (
    <button
      onPointerDown={() => { setDown(true); if (haptic) Haptic.tick(freq); }}
      onPointerUp={() => setDown(false)}
      onPointerLeave={() => setDown(false)}
      onClick={onClick}
      style={{
        border: 'none', background: 'transparent', padding: 0, cursor: 'pointer',
        transition: 'transform 80ms ease', transform: down ? 'scale(.94)' : 'scale(1)',
        WebkitTapHighlightColor: 'transparent', fontFamily: 'inherit',
        ...style,
      }}
      {...rest}
    >{children}</button>
  );
}

// KPI stepper row — "style 3": large number on left, +/- on right divided by hairlines
function StepperRow({ label, value, onChange, dark = false, size = 'lg' }) {
  const ink = dark ? REM.linen : REM.obsidian;
  const muted = dark ? 'rgba(240,238,234,.55)' : REM.inkSubtle;
  const hair = dark ? 'rgba(240,238,234,.14)' : 'rgba(26,26,26,.14)';
  const numSize = size === 'lg' ? 44 : 34;
  const rowH = size === 'lg' ? 88 : 72;
  const btn = 56;

  const set = (v) => onChange(Math.max(0, v));

  return (
    <div style={{ position:'relative' }}>
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr auto auto',
        alignItems: 'center', height: rowH, padding: '0 20px',
        borderBottom: `1px solid ${hair}`,
      }}>
        <div style={{ display:'flex', flexDirection:'column', gap: 6 }}>
          <Eyebrow color={muted}>{label}</Eyebrow>
          <div style={{
            fontFamily: REM.fontDisplay, fontWeight: 500, fontSize: numSize,
            lineHeight: 1, letterSpacing: '-0.02em', color: ink,
            fontVariantNumeric: 'tabular-nums',
          }}>{value}</div>
        </div>
        <Press onClick={() => set(value - 1)} haptic freq={900}
          style={{
            width: btn, height: rowH, display:'grid', placeItems:'center',
            borderLeft: `1px solid ${hair}`, color: ink, opacity: value === 0 ? .3 : 1,
          }}>
          <svg width="18" height="18" viewBox="0 0 18 18"><line x1="3" y1="9" x2="15" y2="9" stroke={ink} strokeWidth="1.5"/></svg>
        </Press>
        <Press onClick={() => set(value + 1)} haptic freq={1700}
          style={{
            width: btn, height: rowH, display:'grid', placeItems:'center',
            borderLeft: `1px solid ${hair}`, color: ink,
          }}>
          <svg width="18" height="18" viewBox="0 0 18 18">
            <line x1="3" y1="9" x2="15" y2="9" stroke={ink} strokeWidth="1.5"/>
            <line x1="9" y1="3" x2="9" y2="15" stroke={ink} strokeWidth="1.5"/>
          </svg>
        </Press>
      </div>
    </div>
  );
}

// Progress hairline bar
function ProgressBar({ pct, dark = false, accent, height = 2 }) {
  const bg = dark ? 'rgba(240,238,234,.15)' : 'rgba(26,26,26,.12)';
  const fg = accent || (dark ? REM.sage : REM.obsidian);
  const w = Math.max(0, Math.min(100, pct));
  return (
    <div style={{ position:'relative', height, background: bg, width: '100%' }}>
      <div style={{ position:'absolute', inset:0, width: `${w}%`, background: fg, transition:'width 300ms ease' }}/>
    </div>
  );
}

// Status dot: green / yellow / red based on pct
function statusColor(pct) {
  if (pct >= 90) return REM.teal;
  if (pct >= 60) return '#C9A227'; // amber, grounded
  return '#B23A2E'; // oxide red
}

function StatusDot({ pct, size = 8 }) {
  return <span style={{ width:size, height:size, borderRadius: 999, background: statusColor(pct), display:'inline-block' }}/>;
}

// Numeric KPI block
function StatBlock({ eyebrow, value, suffix, dark = false }) {
  const ink = dark ? REM.linen : REM.obsidian;
  const muted = dark ? 'rgba(240,238,234,.55)' : REM.inkSubtle;
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
      <Eyebrow color={muted} size={9}>{eyebrow}</Eyebrow>
      <div style={{
        fontFamily: REM.fontDisplay, fontWeight: 500, fontSize: 32, lineHeight: 1,
        letterSpacing:'-0.02em', color: ink, fontVariantNumeric:'tabular-nums',
      }}>{value}{suffix && <span style={{ fontSize:14, color: muted, marginLeft:4 }}>{suffix}</span>}</div>
    </div>
  );
}

Object.assign(window, { REM, Haptic, Wordmark, Eyebrow, Rule, Press, StepperRow, ProgressBar, StatusDot, StatBlock, statusColor });
