// video-core.jsx — Noctua use-case video: shared primitives & artifact components.
// Loaded after animations.jsx (provides Sprite, useSprite, Easing, clamp, interpolate, animate).

const { useSprite, Easing, clamp, interpolate, animate } = window;

// ── Brand tokens (mirror DS so JS can use them directly) ─────────────────────
const C = {
  ink:    '#16140F',
  ink800: '#26231B',
  ink700: '#3A352A',
  ink600: '#57503F',
  ink500: '#7A7261',
  ink400: '#A39A86',
  ink300: '#C9C0AD',
  ink200: '#E3DCCC',
  ink100: '#EFE9DB',
  paper:  '#F6F2E9',
  paperDeep: '#EEE8DA',
  surface:'#FFFFFF',
  surface2:'#FBF8F1',
  green900:'#0B3A2A',
  green700:'#14533C',
  green600:'#1A6B4D',
  green500:'#22875F',
  green400:'#34A878',
  green300:'#6FC9A1',
  green200:'#B6E6CF',
  green100:'#E1F4EA',
  clay500:'#CC6B33',
  clay600:'#B45A28',
  clay100:'#F6E5D6',
  warning:'#B07A12',
  warningBg:'#FBF0D6',
  danger:'#B43A28',
  dangerBg:'#F8E0DB',
};
const FONT = {
  display: 'Verdana, sans-serif',
  body: "'Poppins', Verdana, sans-serif",
  mono: "'IBM Plex Mono', ui-monospace, monospace",
};

// ── small helpers ────────────────────────────────────────────────────────────
const lerp = (a, b, t) => a + (b - a) * t;
// window-local progress inside a sprite: maps [s,e] localTime → 0..1 eased
function win(localTime, s, e, ease = Easing.easeOutCubic) {
  if (e <= s) return localTime >= e ? 1 : 0;
  return ease(clamp((localTime - s) / (e - s), 0, 1));
}

// ── Eyebrow (mono uppercase overline) ────────────────────────────────────────
function Eyebrow({ children, color = C.green600, style }) {
  return (
    <div style={{
      font: '600 22px/1.4 ' + FONT.mono,
      letterSpacing: '0.18em',
      textTransform: 'uppercase',
      color,
      ...style,
    }}>{children}</div>
  );
}

// ── CountUp: animates a number from 0→value across [start,end] localTime ──────
function CountUp({ value, start, end, prefix = '', suffix = '', decimals = 0, style }) {
  const { localTime } = useSprite();
  const p = win(localTime, start, end, Easing.easeOutCubic);
  const cur = value * p;
  const txt = decimals > 0 ? cur.toFixed(decimals) : Math.round(cur).toLocaleString('en-US');
  return <span style={style}>{prefix}{txt}{suffix}</span>;
}

// ── Noctua owl glyph (inline so we can animate stroke draw) ───────────────────
function NoctuaGlyph({ size = 120, color = C.green400, draw = 1, glow = false }) {
  // draw 0..1 controls stroke-dashoffset reveal
  const dash = 240;
  return (
    <svg width={size} height={size} viewBox="0 0 48 48" style={{
      filter: glow ? `drop-shadow(0 0 14px ${color}88)` : 'none',
      overflow: 'visible',
    }}>
      <g fill="none" stroke={color} strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round"
         style={{ strokeDasharray: dash, strokeDashoffset: dash * (1 - draw) }}>
        <path d="M9 13 L24 21 L39 13"></path>
        <circle cx="16" cy="28" r="6.4"></circle>
        <circle cx="32" cy="28" r="6.4"></circle>
      </g>
      <g style={{ opacity: clamp((draw - 0.7) / 0.3, 0, 1) }}>
        <circle cx="16" cy="28" r="2.3" fill={color}></circle>
        <circle cx="32" cy="28" r="2.3" fill={color}></circle>
        <path d="M24 22 L20.5 26 L24 29 L27.5 26 Z" fill={color}></path>
      </g>
    </svg>
  );
}

// ── Panel: a labelled framed surface used for before/after artifacts ──────────
function Panel({ x, y, w, h, children, rotate = 0, tx = 0, ty = 0, opacity = 1, tone = 'paper', accent = false, style }) {
  const bg = tone === 'ink' ? C.ink800 : C.surface;
  const border = tone === 'ink' ? 'rgba(255,255,255,0.12)' : C.ink200;
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: w, height: h,
      background: bg,
      border: `1px solid ${border}`,
      borderTop: accent ? `3px solid ${C.green500}` : `1px solid ${border}`,
      borderRadius: 12,
      boxShadow: '0 18px 44px rgba(22,20,15,0.12), 0 4px 10px rgba(22,20,15,0.06)',
      transform: `translate(${tx}px, ${ty}px) rotate(${rotate}deg)`,
      opacity,
      overflow: 'hidden',
      ...style,
    }}>{children}</div>
  );
}

// window chrome dots for app-like panels
function Chrome({ label, tone = 'light' }) {
  const fg = tone === 'dark' ? 'rgba(255,255,255,0.55)' : C.ink500;
  const bar = tone === 'dark' ? 'rgba(255,255,255,0.07)' : C.surface2;
  const bd = tone === 'dark' ? 'rgba(255,255,255,0.10)' : C.ink100;
  return (
    <div style={{
      height: 40, display: 'flex', alignItems: 'center', gap: 10, padding: '0 16px',
      background: bar, borderBottom: `1px solid ${bd}`,
    }}>
      <div style={{ display: 'flex', gap: 7 }}>
        <span style={{ width: 11, height: 11, borderRadius: 99, background: C.ink300 }}></span>
        <span style={{ width: 11, height: 11, borderRadius: 99, background: C.ink300 }}></span>
        <span style={{ width: 11, height: 11, borderRadius: 99, background: C.ink300 }}></span>
      </div>
      <span style={{ font: '500 14px/1 ' + FONT.mono, letterSpacing: '0.06em', color: fg, textTransform: 'uppercase', whiteSpace: 'nowrap' }}>{label}</span>
    </div>
  );
}

// ── AgentSweep: a bright vertical scan line that crosses [x0,x1] over [s,e] ────
function AgentSweep({ y, h, x0, x1, s, e }) {
  const { localTime } = useSprite();
  const raw = clamp((localTime - s) / (e - s), 0, 1);
  if (raw <= 0 || raw >= 1) return null;
  const x = lerp(x0, x1, Easing.easeInOutCubic(raw));
  return (
    <React.Fragment>
      {/* trailing wash */}
      <div style={{
        position: 'absolute', left: x0, top: y, width: x - x0, height: h,
        background: `linear-gradient(90deg, ${C.green400}00, ${C.green400}1f)`,
      }}></div>
      {/* the line */}
      <div style={{
        position: 'absolute', left: x - 2, top: y - 14, width: 4, height: h + 28,
        background: C.green400, borderRadius: 2,
        boxShadow: `0 0 22px 4px ${C.green400}cc`,
      }}></div>
    </React.Fragment>
  );
}

// ── Status badge (lead-state pills) ──────────────────────────────────────────
function Badge({ children, tone = 'qualified', big = false }) {
  const map = {
    qualified: [C.green100, C.green700, C.green500],
    review:    [C.warningBg, C.warning, C.warning],
    sent:      [C.green100, C.green700, C.green500],
    cold:      [C.dangerBg, C.danger, C.danger],
    neutral:   [C.ink100, C.ink700, C.ink400],
  };
  const [bg, fg, dot] = map[tone] || map.neutral;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      background: bg, color: fg,
      font: `600 ${big ? 17 : 14}px/1 ${FONT.mono}`,
      letterSpacing: '0.06em', textTransform: 'uppercase',
      padding: big ? '9px 16px' : '6px 11px', borderRadius: 99,
    }}>
      <span style={{ width: big ? 9 : 7, height: big ? 9 : 7, borderRadius: 99, background: dot }}></span>
      {children}
    </span>
  );
}

// ── MetricBadge: big number that counts up + label, used at scene bottom ──────
function MetricStat({ value, start, end, prefix = '', suffix = '', decimals = 0, label, accent = C.green600 }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ font: '700 76px/1 ' + FONT.display, letterSpacing: '-0.03em', color: accent }}>
        <CountUp value={value} start={start} end={end} prefix={prefix} suffix={suffix} decimals={decimals} />
      </div>
      <div style={{ font: '500 21px/1.3 ' + FONT.body, color: C.ink600, maxWidth: 360 }}>{label}</div>
    </div>
  );
}

// ── Spreadsheet artifact (Excel-ish) ─────────────────────────────────────────
function Spreadsheet({ messy = false }) {
  const cols = ['A', 'B', 'C', 'D'];
  const rows = 6;
  return (
    <div style={{ padding: 0, height: '100%', display: 'flex', flexDirection: 'column' }}>
      <div style={{ display: 'grid', gridTemplateColumns: `46px repeat(${cols.length}, 1fr)`, flex: 1 }}>
        <div style={{ background: C.surface2, borderRight: `1px solid ${C.ink100}` }}></div>
        {cols.map((c) => (
          <div key={c} style={{ background: C.surface2, borderRight: `1px solid ${C.ink100}`, borderBottom: `1px solid ${C.ink100}`,
            font: '600 13px/1 ' + FONT.mono, color: C.ink500, display: 'flex', alignItems: 'center', justifyContent: 'center', height: 30 }}>{c}</div>
        ))}
        {Array.from({ length: rows }).flatMap((_, r) => [
          <div key={'h' + r} style={{ background: C.surface2, borderRight: `1px solid ${C.ink100}`, borderBottom: `1px solid ${C.ink100}`,
            font: '600 13px/1 ' + FONT.mono, color: C.ink400, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{r + 1}</div>,
          ...cols.map((c, ci) => {
            const filled = (r * 4 + ci) % 3 !== 2;
            return (
              <div key={c + r} style={{ borderRight: `1px solid ${C.ink100}`, borderBottom: `1px solid ${C.ink100}`,
                display: 'flex', alignItems: 'center', padding: '0 10px', height: 32,
                font: '400 13px/1 ' + FONT.mono, color: messy && ci === 2 ? C.danger : C.ink600,
                background: messy && ((r + ci) % 5 === 0) ? C.dangerBg : 'transparent' }}>
                {filled ? (ci === 0 ? `#${1042 + r * 3}` : ci === 3 ? `$${(r * 137 + 84)}` : (messy && ci === 2 ? '#ERR' : `${(r * 7 + ci * 3) % 90}`)) : ''}
              </div>
            );
          }),
        ])}
      </div>
    </div>
  );
}

// ── Invoice / PDF doc artifact ───────────────────────────────────────────────
function DocArtifact({ kind = 'PDF', title = 'INVOICE', unsent = false }) {
  const tag = kind === 'PDF' ? C.danger : kind === 'DOC' ? '#2A5F6B' : C.green600;
  return (
    <div style={{ padding: '22px 24px', height: '100%', position: 'relative' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div style={{ font: '700 22px/1 ' + FONT.display, letterSpacing: '-0.02em', color: C.ink }}>{title}</div>
        <span style={{ font: '700 12px/1 ' + FONT.mono, color: '#fff', background: tag, padding: '5px 9px', borderRadius: 5, letterSpacing: '0.08em' }}>{kind}</span>
      </div>
      <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 10 }}>
        {[0, 1, 2, 3].map((i) => (
          <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ height: 9, width: `${52 - i * 7}%`, background: C.ink100, borderRadius: 3 }}></div>
            <div style={{ font: '500 14px/1 ' + FONT.mono, color: C.ink500 }}>${(i + 2) * 145}</div>
          </div>
        ))}
      </div>
      <div style={{ position: 'absolute', left: 24, right: 24, bottom: 18, display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        borderTop: `1px solid ${C.ink100}`, paddingTop: 12 }}>
        <span style={{ font: '600 13px/1 ' + FONT.mono, color: C.ink500, textTransform: 'uppercase', letterSpacing: '0.06em' }}>Total due</span>
        <span style={{ font: '700 22px/1 ' + FONT.display, color: C.ink }}>$1,964</span>
      </div>
      {unsent && (
        <div style={{ position: 'absolute', top: 64, right: -6, transform: 'rotate(8deg)',
          font: '700 13px/1 ' + FONT.mono, color: C.danger, border: `2px solid ${C.danger}`, padding: '5px 9px', borderRadius: 6, letterSpacing: '0.08em' }}>UNSENT</div>
      )}
    </div>
  );
}

// ── Phone / missed-call artifact ─────────────────────────────────────────────
function PhoneArtifact() {
  return (
    <div style={{ padding: '20px 22px', height: '100%', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ font: '600 13px/1 ' + FONT.mono, color: C.ink500, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Recents</div>
      {[['Missed call', '9:47 PM', true], ['Voicemail', '9:12 PM', true], ['New lead — web form', '8:30 PM', true]].map(([t, time, miss], i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ width: 38, height: 38, borderRadius: 99, background: C.dangerBg, color: C.danger,
            display: 'flex', alignItems: 'center', justifyContent: 'center', font: '700 16px/1 ' + FONT.display }}>↙</span>
          <div style={{ flex: 1 }}>
            <div style={{ font: '500 17px/1.2 ' + FONT.body, color: C.ink }}>{t}</div>
            <div style={{ font: '400 13px/1 ' + FONT.mono, color: C.danger }}>{time}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Sticky note ──────────────────────────────────────────────────────────────
function Sticky({ children, rotate = -3, color = '#F7E59B', x, y, w = 230 }) {
  return (
    <div style={{ position: 'absolute', left: x, top: y, width: w, minHeight: w * 0.78,
      background: color, transform: `rotate(${rotate}deg)`,
      boxShadow: '0 10px 22px rgba(22,20,15,0.16)', padding: '18px 18px',
      font: "italic 500 21px/1.35 " + FONT.body, color: '#5A4B12' }}>{children}</div>
  );
}

// ── Calendar grid artifact ───────────────────────────────────────────────────
function CalendarArtifact({ booked = false }) {
  return (
    <div style={{ padding: '18px 20px', height: '100%' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 12 }}>
        {['M', 'T', 'W', 'T', 'F'].map((d, i) => (
          <span key={i} style={{ font: '600 14px/1 ' + FONT.mono, color: C.ink500, width: 56, textAlign: 'center' }}>{d}</span>
        ))}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5,1fr)', gridAutoRows: '52px', gap: 6 }}>
        {Array.from({ length: 15 }).map((_, i) => {
          const slot = booked ? (i % 3 === 0) : (i === 4 || i === 9);
          return (
            <div key={i} style={{ borderRadius: 6, border: `1px solid ${C.ink100}`,
              background: slot ? (booked ? C.green100 : C.dangerBg) : C.surface2,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              font: '600 12px/1 ' + FONT.mono, color: slot ? (booked ? C.green700 : C.danger) : C.ink300 }}>
              {slot ? (booked ? '✓' : '✗✗') : ''}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── Review card with stars ───────────────────────────────────────────────────
function ReviewArtifact({ filled = 0 }) {
  return (
    <div style={{ padding: '22px 24px', height: '100%', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'flex', gap: 6 }}>
        {[0, 1, 2, 3, 4].map((i) => (
          <span key={i} style={{ font: '28px/1 ' + FONT.display, color: i < filled ? C.clay500 : C.ink200 }}>★</span>
        ))}
      </div>
      <div style={{ height: 9, width: '82%', background: C.ink100, borderRadius: 3 }}></div>
      <div style={{ height: 9, width: '64%', background: C.ink100, borderRadius: 3 }}></div>
      <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{ width: 34, height: 34, borderRadius: 99, background: C.green600, color: '#fff',
          display: 'flex', alignItems: 'center', justifyContent: 'center', font: '600 14px/1 ' + FONT.body }}>DR</span>
        <span style={{ font: '500 15px/1 ' + FONT.body, color: C.ink600 }}>Dana R.</span>
      </div>
    </div>
  );
}

// ── Agent message bubble (the "after" output for several scenes) ──────────────
function AgentReply({ lines, name = 'Lead Response', typed = 1 }) {
  return (
    <div style={{ padding: '20px 22px', height: '100%', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <NoctuaGlyph size={28} color={C.green600} />
        <span style={{ font: '600 15px/1 ' + FONT.mono, color: C.green700, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{name} agent</span>
      </div>
      <div style={{ background: C.green100, border: `1px solid ${C.green200}`, borderRadius: '4px 14px 14px 14px',
        padding: '14px 16px', maxWidth: '94%' }}>
        {lines.map((l, i) => (
          <div key={i} style={{ font: '400 17px/1.5 ' + FONT.body, color: C.ink700,
            opacity: clamp((typed - i * 0.34) / 0.34, 0, 1) }}>{l}</div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  C, FONT, lerp, win, Eyebrow, CountUp, NoctuaGlyph, Panel, Chrome, AgentSweep,
  Badge, MetricStat, Spreadsheet, DocArtifact, PhoneArtifact, Sticky,
  CalendarArtifact, ReviewArtifact, AgentReply,
});
