// ui.jsx - shared primitives: Pill, Eyebrow, TagChip, RenderFrame, Stats, Reveal
const { useState: useStateU, useEffect: useEffectU, useRef: useRefU } = React;

/* The system-wide scale(0.95) press micro-interaction. */
const pressHandlers = {
  onMouseDown: e => { e.currentTarget.style.transform = 'scale(0.95)'; },
  onMouseUp:   e => { e.currentTarget.style.transform = 'scale(1)'; },
  onMouseLeave:e => { e.currentTarget.style.transform = 'scale(1)'; },
};

function Pill({ children, variant = 'primary', dark = false, onClick, as = 'button', href, size = 'md' }) {
  const pad = size === 'lg' ? '14px 26px' : '11px 22px';
  const base = {
    borderRadius: 9999, padding: pad, fontSize: size === 'lg' ? 18 : 17, cursor: 'pointer',
    fontFamily: 'var(--font-text)', transition: 'transform .12s ease, opacity .2s ease',
    letterSpacing: '-0.374px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center',
    gap: 8, lineHeight: 1.2, whiteSpace: 'nowrap',
  };
  const skin = variant === 'primary'
    ? { background: dark ? 'var(--primary-on-dark)' : 'var(--primary)', color: dark ? '#001a33' : '#fff', border: 0 }
    : { background: 'transparent', color: dark ? 'var(--primary-on-dark)' : 'var(--primary)',
        border: `1px solid ${dark ? 'var(--primary-on-dark)' : 'var(--primary)'}`,
        padding: size === 'lg' ? '13px 25px' : '10px 21px' };
  const props = { style: { ...base, ...skin }, ...pressHandlers };
  if (as === 'a') return <a href={href} target={href && href.startsWith('http') ? '_blank' : undefined} rel="noreferrer" onClick={onClick} {...props}>{children}</a>;
  return <button onClick={onClick} {...props}>{children}</button>;
}

/* Tracked-out uppercase caption label. */
function Eyebrow({ children, dark = false, style }) {
  return (
    <span className="t-caption" style={{
      textTransform: 'uppercase', letterSpacing: '0.16em', fontSize: 12, fontWeight: 600,
      color: dark ? 'var(--body-muted)' : 'var(--ink-muted-48)', ...style,
    }}>{children}</span>
  );
}

/* Hairline discipline / tech chip. */
function TagChip({ children, dark = false, accent = false }) {
  return (
    <span className="t-caption" style={{
      color: accent ? (dark ? 'var(--primary-on-dark)' : 'var(--primary)') : (dark ? 'var(--body-muted)' : 'var(--ink-muted-80)'),
      border: `1px solid ${accent ? (dark ? 'var(--primary-on-dark)' : 'var(--primary)') : (dark ? 'rgba(255,255,255,0.22)' : 'var(--hairline)')}`,
      background: dark ? 'rgba(255,255,255,0.04)' : '#fff',
      borderRadius: 9999, padding: '6px 13px', whiteSpace: 'nowrap',
    }}>{children}</span>
  );
}

/* Pick a placeholder glyph from the project's planned media type. */
function mediaIcon(media = '') {
  const m = media.toLowerCase();
  if (/plot|scorecard|matri|regression|fea/.test(m)) return 'spark';
  if (/screenshot|ui|cli/.test(m)) return 'doc';
  return 'image';
}

/* Render-frame: stands in for real imagery; carries the ONE system shadow. */
function RenderFrame({ p, ratio = '16 / 10', radius = 12, minH }) {
  const common = {
    width: '100%', aspectRatio: minH ? undefined : ratio, minHeight: minH,
    borderRadius: radius, boxShadow: 'var(--shadow-product)', overflow: 'hidden', position: 'relative',
  };
  if (p.image) {
    const fit = p.imageFit || 'cover';
    return (
      <div style={{ ...common, background: fit === 'contain' ? 'var(--canvas-parchment)' : '#000' }}>
        <img src={p.image} alt={p.name} loading="lazy" style={{ width: '100%', height: '100%', objectFit: fit, display: 'block' }} />
      </div>
    );
  }
  return (
    <div style={{ ...common, background: p.panel, display: 'grid', placeItems: 'center' }}>
      {/* faint texture so the panel reads as 'imagery to come', not a flat block */}
      <div style={{ position: 'absolute', inset: 0, opacity: 0.5,
        backgroundImage: 'repeating-linear-gradient(135deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 11px)' }} />
      <div style={{ position: 'relative', textAlign: 'center', color: 'rgba(255,255,255,0.82)', padding: 24 }}>
        <Icon name={mediaIcon(p.media)} size={28} color="currentColor" strokeWidth={1.5} style={{ opacity: 0.92 }} />
        <div className="t-caption" style={{ marginTop: 10, letterSpacing: '-0.2px' }}>{p.media}</div>
        <div style={{ display: 'inline-block', marginTop: 12, padding: '4px 11px', borderRadius: 9999,
          border: '1px solid rgba(255,255,255,0.28)', fontSize: 11, letterSpacing: '0.08em',
          textTransform: 'uppercase', color: 'rgba(255,255,255,0.7)' }}>Placeholder</div>
      </div>
    </div>
  );
}

/* Gallery media item: image, autoplay-loop video, click-to-play video, embed, or
   a PDF view/download row. Captions are optional. Items can span the full grid. */
function MediaCaption({ children }) {
  if (!children) return null;
  return <p className="t-caption" style={{ color: 'var(--ink-muted-48)', margin: '12px 4px 0', textAlign: 'center', textWrap: 'pretty' }}>{children}</p>;
}

function MediaItem({ item }) {
  const ratio = item.ratio || '16 / 9';
  const fit = item.fit || 'contain';
  const frame = {
    width: '100%', borderRadius: 12, overflow: 'hidden',
    boxShadow: 'var(--shadow-product)', position: 'relative',
  };

  if (item.type === 'pdf') {
    return (
      <a href={item.src} target="_blank" rel="noreferrer" className="row-link" style={{
        display: 'flex', alignItems: 'center', gap: 16, textDecoration: 'none',
        border: '1px solid var(--hairline)', borderRadius: 14, padding: '18px 20px', background: '#fff' }}>
        <Icon name="doc" size={24} color="var(--primary)" strokeWidth={1.6} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="t-body-strong" style={{ color: 'var(--ink)' }}>{item.label || 'Document (PDF)'}</div>
          {item.note && <div className="t-caption" style={{ color: 'var(--ink-muted-48)', marginTop: 2 }}>{item.note}</div>}
        </div>
        <Icon name="arrowUR" size={18} color="var(--ink-muted-48)" />
      </a>
    );
  }

  if (item.type === 'embed') {
    return (
      <div>
        <div style={{ ...frame, paddingBottom: '56.25%', height: 0, background: '#000' }}>
          <iframe src={item.src} title={item.caption || 'Embedded video'} frameBorder="0" allowFullScreen
            style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }} />
        </div>
        <MediaCaption>{item.caption}</MediaCaption>
      </div>
    );
  }

  if (item.type === 'video') {
    /* small clips: autoplay, muted, looped. Ref forces muted+play for autoplay policy. */
    return (
      <div>
        <div style={{ ...frame, aspectRatio: ratio, background: '#0c0c0c' }}>
          <video ref={el => { if (el) { el.muted = true; const pr = el.play(); if (pr && pr.catch) pr.catch(() => {}); } }}
            autoPlay muted loop playsInline preload="auto"
            style={{ width: '100%', height: '100%', objectFit: fit, display: 'block' }}>
            <source src={item.src} type="video/mp4" />
          </video>
        </div>
        <MediaCaption>{item.caption}</MediaCaption>
      </div>
    );
  }

  if (item.type === 'videoControls') {
    /* large or non-mp4 clips: click to play, do not preload. */
    return (
      <div>
        <div style={{ ...frame, aspectRatio: ratio, background: '#0c0c0c' }}>
          <video controls preload="none" playsInline poster={item.poster}
            style={{ width: '100%', height: '100%', objectFit: fit, display: 'block', background: '#0c0c0c' }}>
            <source src={item.src} />
          </video>
        </div>
        <MediaCaption>{item.caption}</MediaCaption>
      </div>
    );
  }

  // image: cover fills a fixed-ratio frame; contain shows the full image at its
  // natural ratio (best for charts, scorecards, CAD, and diagrams).
  if (fit === 'cover') {
    return (
      <div>
        <div style={{ ...frame, aspectRatio: ratio, background: '#000' }}>
          <img src={item.src} alt={item.caption || ''} loading="lazy"
            style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
        </div>
        <MediaCaption>{item.caption}</MediaCaption>
      </div>
    );
  }
  return (
    <div>
      <div style={{ ...frame, background: 'var(--canvas-parchment)' }}>
        <img src={item.src} alt={item.caption || ''} loading="lazy"
          style={{ width: '100%', height: 'auto', display: 'block' }} />
      </div>
      <MediaCaption>{item.caption}</MediaCaption>
    </div>
  );
}

/* Stat row - display figures + caption labels. */
function Stats({ results, dark = false, align = 'flex-start', gap = 44 }) {
  if (!results || !results.length) return null;
  return (
    <div style={{ display: 'flex', gap, justifyContent: align, flexWrap: 'wrap' }}>
      {results.map((r, i) => (
        <div key={i} style={{ maxWidth: 200 }}>
          <div className="t-display-md" style={{ color: dark ? '#fff' : 'var(--ink)', fontWeight: 600, lineHeight: 1.05 }}>{r.v}</div>
          <div className="t-caption" style={{ color: dark ? 'var(--body-muted)' : 'var(--ink-muted-48)', marginTop: 6 }}>{r.l}</div>
        </div>
      ))}
    </div>
  );
}

/* Reveal: content is always visible. Entrance animations are intentionally
   omitted - a frozen/backgrounded timeline (preview pane, print, PDF export)
   would otherwise freeze an opacity fade at its invisible first frame. The
   liveliness lives in hover/press micro-interactions instead. Kept as a thin
   wrapper so call sites can pass layout `style`/`as`/`delay` uniformly. */
const REDUCED = typeof window !== 'undefined' && window.matchMedia &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;

function Reveal({ children, style, as = 'div' }) {
  const Tag = as;
  return <Tag style={style}>{children}</Tag>;
}

Object.assign(window, { Pill, Eyebrow, TagChip, RenderFrame, MediaItem, MediaCaption, Stats, Reveal, pressHandlers, mediaIcon });
