// scenes.jsx — DeftForge animated video scenes
// Story arc: raw work → forging → forged tool → working system → logo reveal → CTA
//
// Palette:
//   bg #0a0a0b · fg #f5f5f4 · ember #ff6b35 · panel #15151a · dim #6b6b72

const COLORS = {
  bg:      '#0a0a0b',
  panel:   '#15151a',
  panel2:  '#1c1c22',
  fg:      '#f5f5f4',
  dim:     '#6b6b72',
  faint:   '#2a2a30',
  ember:   '#ff6b35',
  emberHi: '#ffa872',
};

const FONT_SANS = 'Inter, system-ui, sans-serif';
const FONT_MONO = 'JetBrains Mono, ui-monospace, SFMono-Regular, monospace';

// ── Helpers ─────────────────────────────────────────────────────────────────
const lerp = (a, b, t) => a + (b - a) * t;

// Subtle ambient grain — keeps frames from feeling static
function Grain({ opacity = 0.04 }) {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      backgroundImage: 'url("data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22><filter id=%22n%22><feTurbulence baseFrequency=%220.9%22 numOctaves=%222%22/></filter><rect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23n)%22 opacity=%220.6%22/></svg>")',
      opacity,
      mixBlendMode: 'overlay',
      pointerEvents: 'none',
    }} />
  );
}

// Scanline / faint vignette to ground every shot
function Vignette() {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: 'radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.6) 100%)',
      pointerEvents: 'none',
    }} />
  );
}

// ── Sparks particle system ─────────────────────────────────────────────────
// Deterministic per-spark seed so positions are stable per render
function Sparks({ count = 24, originX = 960, originY = 540, intensity = 1, color = COLORS.ember }) {
  const { localTime, duration, progress } = useSprite();
  const sparks = React.useMemo(() => {
    const out = [];
    for (let i = 0; i < count; i++) {
      const seed = i * 137.5;
      const angle = (Math.sin(seed) * 0.5 + 0.5) * Math.PI - Math.PI / 2; // upper hemisphere
      const speed = 200 + (Math.cos(seed * 1.3) * 0.5 + 0.5) * 600;
      const life = 0.6 + (Math.sin(seed * 2.1) * 0.5 + 0.5) * 0.8;
      const delay = (Math.cos(seed * 0.7) * 0.5 + 0.5) * 0.4;
      const size = 2 + (Math.sin(seed * 3.3) * 0.5 + 0.5) * 4;
      out.push({ angle, speed, life, delay, size });
    }
    return out;
  }, [count]);

  return (
    <>
      {sparks.map((s, i) => {
        const t = localTime - s.delay;
        if (t < 0 || t > s.life) return null;
        const lt = t / s.life;
        const dist = s.speed * t;
        const gravity = 600 * t * t;
        const dx = Math.cos(s.angle) * dist;
        const dy = Math.sin(s.angle) * dist + gravity;
        const opacity = (1 - lt) * intensity;
        const scale = 1 - lt * 0.7;
        return (
          <div key={i} style={{
            position: 'absolute',
            left: originX + dx,
            top: originY + dy,
            width: s.size,
            height: s.size,
            background: color,
            borderRadius: '50%',
            opacity,
            transform: `scale(${scale})`,
            boxShadow: `0 0 ${s.size * 3}px ${color}`,
            pointerEvents: 'none',
          }} />
        );
      })}
    </>
  );
}

// Heat glow at the forge point
function ForgeGlow({ x, y, radius = 400, intensity = 1 }) {
  return (
    <div style={{
      position: 'absolute',
      left: x - radius,
      top: y - radius,
      width: radius * 2,
      height: radius * 2,
      background: `radial-gradient(circle, ${COLORS.ember}${Math.floor(intensity * 0.6 * 255).toString(16).padStart(2, '0')} 0%, transparent 60%)`,
      pointerEvents: 'none',
      mixBlendMode: 'screen',
    }} />
  );
}

// ── Scene 1 — Cold open: raw manual work ───────────────────────────────────
// 0.0 → 5.5s
// Camera: tight on a chaotic to-do list / spreadsheet of manual ops.
// Beat 1 (0.3s): "Manual." slams in
// Beat 2 (1.2s): list of repeating tasks scrolls
// Beat 3 (3.5s): all tasks turn into one word: "Hours."
function Scene1ColdOpen() {
  const { localTime, progress } = useSprite();

  // Tasks in the "queue"
  const tasks = [
    'tag-incoming-leads',
    'reconcile-stripe-vs-ledger',
    'summarize-support-thread',
    'route-rfp-to-eng',
    'draft-followup-email',
    'extract-line-items.pdf',
    'classify-bug-report',
    'sync-hubspot-↔-airtable',
    'tag-incoming-leads',
    'reconcile-stripe-vs-ledger',
    'summarize-support-thread',
    'route-rfp-to-eng',
  ];

  const sceneDur = 5.5;
  // Camera zoom: starts wide-ish, slowly pushes in
  const camScale = lerp(1.0, 1.12, Easing.easeInOutCubic(progress));
  const camX = lerp(0, -40, Easing.easeInOutCubic(progress));

  // Scroll velocity peaks then collapses around 3.5s
  const collapseT = clamp((localTime - 3.3) / 1.2, 0, 1);
  const scrollSpeed = lerp(40, 380, Easing.easeInQuad(clamp(localTime / 3.0, 0, 1)));
  const scrollY = -localTime * scrollSpeed;

  // List opacity collapses at end as "Hours." takes over
  const listOpacity = 1 - Easing.easeInQuad(collapseT);

  // Heading text
  const headingOpacity = clamp(localTime / 0.4, 0, 1);

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: COLORS.bg,
      overflow: 'hidden',
      transform: `scale(${camScale}) translateX(${camX}px)`,
      transformOrigin: 'center',
    }}>
      {/* Top label */}
      <div style={{
        position: 'absolute', left: 80, top: 80,
        fontFamily: FONT_MONO,
        fontSize: 16,
        color: COLORS.dim,
        letterSpacing: '0.16em',
        textTransform: 'uppercase',
        opacity: headingOpacity,
      }}>
        ops/queue · live
      </div>

      {/* Scrolling task list */}
      <div style={{
        position: 'absolute',
        left: 80, right: 80, top: 180, bottom: 80,
        overflow: 'hidden',
        opacity: listOpacity,
      }}>
        <div style={{
          transform: `translateY(${scrollY}px)`,
          willChange: 'transform',
        }}>
          {[...tasks, ...tasks, ...tasks, ...tasks].map((t, i) => (
            <div key={i} style={{
              display: 'flex',
              alignItems: 'center',
              gap: 24,
              padding: '20px 0',
              borderBottom: `1px solid ${COLORS.faint}`,
              fontFamily: FONT_MONO,
              fontSize: 28,
              color: i % 7 === 0 ? COLORS.fg : COLORS.dim,
            }}>
              <span style={{
                color: COLORS.dim,
                width: 60,
              }}>
                {String(i + 1).padStart(3, '0')}
              </span>
              <span style={{ flex: 1 }}>{t}</span>
              <span style={{
                fontSize: 14,
                padding: '4px 10px',
                border: `1px solid ${COLORS.faint}`,
                borderRadius: 4,
                color: COLORS.dim,
                letterSpacing: '0.08em',
              }}>
                MANUAL
              </span>
            </div>
          ))}
        </div>
      </div>

      {/* Vertical fade at top + bottom */}
      <div style={{
        position: 'absolute', top: 160, left: 0, right: 0, height: 120,
        background: `linear-gradient(${COLORS.bg}, transparent)`,
        pointerEvents: 'none',
      }} />
      <div style={{
        position: 'absolute', bottom: 60, left: 0, right: 0, height: 200,
        background: `linear-gradient(transparent, ${COLORS.bg})`,
        pointerEvents: 'none',
      }} />

      {/* "Hours." reveal */}
      {localTime > 3.5 && (
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          opacity: clamp((localTime - 3.5) / 0.5, 0, 1),
        }}>
          <div style={{
            fontFamily: FONT_SANS,
            fontWeight: 800,
            fontSize: 280,
            color: COLORS.fg,
            letterSpacing: '-0.05em',
            transform: `scale(${lerp(1.3, 1.0, Easing.easeOutCubic(clamp((localTime - 3.5) / 0.5, 0, 1)))})`,
          }}>
            hours.
          </div>
        </div>
      )}

      <Grain opacity={0.05} />
    </div>
  );
}

// ── Scene 2 — The forge moment ─────────────────────────────────────────────
// 5.5 → 11.5s
// "Hours." compresses → glows → SPARKS → reveals "forge"
// Beat: heat builds, climax at ~8s with full spark explosion, then settles.
function Scene2Forge() {
  const { localTime, progress } = useSprite();
  const dur = 6.0;

  // Heating phase (0→2s): "hours." compresses, ember rises
  const heatT = clamp(localTime / 2.0, 0, 1);
  // Hammer strike at 2.0s
  const strikeT = clamp((localTime - 2.0) / 0.15, 0, 1);
  // Cooling/settle (2.5 → 6s): spark fade, "forge" emerges
  const settleT = clamp((localTime - 2.3) / 1.2, 0, 1);
  const forgeT = clamp((localTime - 3.0) / 1.5, 0, 1);

  // Pre-strike: text shakes harder as heat builds
  const shakeAmt = heatT * 8 * (1 - strikeT);
  const shakeX = Math.sin(localTime * 80) * shakeAmt;
  const shakeY = Math.cos(localTime * 70) * shakeAmt;

  // Strike: text scales down & glows white-hot
  const strikeScale = lerp(1, 0.4, Easing.easeInQuart(strikeT));
  const strikeOpacity = 1 - Easing.easeOutCubic(strikeT);

  // Glow intensity peaks at strike
  const glowI = heatT * (1 - settleT);

  // White flash at strike moment
  const flashOpacity = strikeT < 1
    ? Math.max(0, 1 - Math.abs(localTime - 2.05) / 0.18)
    : 0;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: COLORS.bg,
      overflow: 'hidden',
    }}>
      {/* Forge glow */}
      <ForgeGlow x={960} y={540} radius={700} intensity={glowI} />

      {/* "hours." being struck */}
      {strikeOpacity > 0 && (
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          transform: `translate(${shakeX}px, ${shakeY}px) scale(${strikeScale})`,
        }}>
          <div style={{
            fontFamily: FONT_SANS,
            fontWeight: 800,
            fontSize: 280,
            letterSpacing: '-0.05em',
            color: COLORS.fg,
            opacity: strikeOpacity,
            textShadow: heatT > 0.3
              ? `0 0 ${heatT * 60}px ${COLORS.ember}, 0 0 ${heatT * 30}px ${COLORS.emberHi}`
              : 'none',
            filter: heatT > 0.7 ? `brightness(${1 + heatT * 0.5})` : 'none',
          }}>
            hours.
          </div>
        </div>
      )}

      {/* Sparks burst at strike */}
      {localTime > 1.9 && localTime < 4.0 && (
        <div style={{ position: 'absolute', inset: 0 }}>
          <Sparks
            count={48}
            originX={960}
            originY={540}
            intensity={clamp((localTime - 1.9) / 0.2, 0, 1) * (1 - clamp((localTime - 3.0) / 1.0, 0, 1))}
          />
        </div>
      )}

      {/* White flash */}
      <div style={{
        position: 'absolute', inset: 0,
        background: '#fff',
        opacity: flashOpacity,
        pointerEvents: 'none',
      }} />

      {/* "forge." reveal */}
      {forgeT > 0 && (
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          opacity: Easing.easeOutCubic(forgeT),
        }}>
          <div style={{
            fontFamily: FONT_SANS,
            fontWeight: 800,
            fontSize: 280,
            letterSpacing: '-0.05em',
            color: COLORS.fg,
            transform: `scale(${lerp(1.15, 1.0, Easing.easeOutCubic(forgeT))})`,
            display: 'inline-flex',
            alignItems: 'baseline',
          }}>
            <span>forge</span>
            <span style={{ color: COLORS.ember }}>.</span>
          </div>
        </div>
      )}

      {/* Subtitle that emerges under "forge." */}
      {localTime > 4.2 && (
        <div style={{
          position: 'absolute',
          left: 0, right: 0, top: '64%',
          textAlign: 'center',
          fontFamily: FONT_MONO,
          fontSize: 22,
          color: COLORS.dim,
          letterSpacing: '0.18em',
          textTransform: 'uppercase',
          opacity: clamp((localTime - 4.2) / 0.6, 0, 1),
        }}>
          custom ai · built for your ops
        </div>
      )}

      <Grain opacity={0.05} />
    </div>
  );
}

Object.assign(window, {
  COLORS, FONT_SANS, FONT_MONO, lerp,
  Grain, Vignette, Sparks, ForgeGlow,
  Scene1ColdOpen, Scene2Forge,
});
