// @ts-nocheck
// ============================================================================
// MOTION GRAPHICS · OBSIDIAN ORBIT — Scene 15 / GENERATE → PREVIEW  (13s, 390f)
//
// "Keynote object-worship". ONE hero artifact: the GENERATION slab. A thick
// glass slab whose face is a render farm — a GRID of asset tiles that fill in
// one-by-one as a progress bar climbs ("GENERATING…"). When the grid completes,
// a "Launch Motion Studio" button lights up and is clicked; the face transitions
// into a STUDIO PREVIEW where a play head scrubs across a row of scene
// thumbnails. The WORLD orbits (never the camera) in slow hold→ease arcs; spec
// Callouts billboard on drawn leader lines ("GENERATING…", "LAUNCH STUDIO",
// "13s PREVIEW"); the angle-tracked sheen rakes the turn. A riser builds into
// the launch where the slab LOCKS straight-on with an impact + shockwave — the
// payoff — then settles into the scrubbing studio, sheen tracking the final turn.
//
// Built ENTIRELY on the Plinth module (mirrors ObsidianOrbit.tsx's contract) +
// the shared Chronixel engine. CSS-3D only, deterministic, no WebGL.
// ============================================================================
import React from "react";
import { AbsoluteFill, useCurrentFrame, useVideoConfig } from "remotion";

import {
  Plinth,
  OrbitWorld,
  Extrude,
  Callout,
  DustMotes,
} from "../../plinth/plinth";
import { C, withAlpha, ACCENT_GRAD } from "../../chronixel/theme";
import { FONT, MONO } from "../../chronixel/fonts";
import {
  beat,
  clamp01,
  mix,
  osc,
  enter,
  springAt,
  EASE,
  SPRING,
} from "../../chronixel/motion";
import { Shockwave, GlowPulse, LightSweep } from "../../chronixel/fx";

/* ----------------------------------------------------------------------------
   A small mono eyebrow tag pinned top-left over the void — frames the beat.
   -------------------------------------------------------------------------- */
const Eyebrow: React.FC<{ at: number; children: React.ReactNode }> = ({
  at,
  children,
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  return (
    <div
      style={{
        position: "absolute",
        left: 120,
        top: 120,
        display: "flex",
        alignItems: "center",
        gap: 14,
        fontFamily: MONO,
        fontSize: 15,
        letterSpacing: 5,
        textTransform: "uppercase",
        color: C.accent2,
        ...enter(frame, fps, at, { from: "left", dist: 32, blur: 0 }),
      }}
    >
      <span
        style={{
          width: 30,
          height: 2,
          background: ACCENT_GRAD,
          boxShadow: `0 0 12px ${C.accentGlow}`,
        }}
      />
      {children}
    </div>
  );
};

/* ============================================================================
   GENERATE → PREVIEW. Hero = the generation slab. A 4x3 grid of asset tiles
   fills in one-by-one while a progress bar climbs; at completion a "Launch
   Motion Studio" button is clicked and the face flips to a studio preview where
   a play head scrubs across scene thumbnails. World orbits in, callouts fire,
   slab LOCKS front-on at the launch, then settles into the scrubbing studio.
   ========================================================================== */
export const MgOrbitScene15Generate: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const t = frame / fps;

  const LOCK = 8.4; // the launch lock-in beat (seconds) — the payoff

  // --- generation grid: 12 tiles fill one-by-one ------------------------
  const COLS = 4;
  const ROWS = 3;
  const TILES = COLS * ROWS;
  const GEN_START = 1.0; // first tile begins
  const GEN_STEP = 0.42; // seconds between tiles igniting
  const GEN_FILL = 0.5; // seconds for a tile to pop in

  // overall generation progress 0→1 (drives the bar + the "GENERATING…" %).
  const genLast = GEN_START + (TILES - 1) * GEN_STEP + GEN_FILL;
  const genProg = clamp01((t - GEN_START) / (genLast - GEN_START));
  const genPct = Math.round(100 * genProg);
  const genDone = genProg >= 1;

  // --- launch button: lights once grid is full, clicked at the lock ------
  const BTN_LIVE = genLast; // button becomes live when grid completes
  const btnIn = beat(frame, fps, BTN_LIVE, BTN_LIVE + 0.5, EASE.backOut);
  const btnGlow = 0.5 + 0.5 * osc(t, 1.4);
  const press = beat(frame, fps, LOCK - 0.18, LOCK, EASE.out); // click depress
  const pressScale = 1 - 0.06 * (press - clamp01((t - LOCK) / 0.18));

  // --- studio preview: opens at the launch, play head scrubs -------------
  const studioOpen = beat(frame, fps, LOCK, LOCK + 0.8, EASE.expoOut);
  // play head sweeps left→right across the thumbnail strip, looping gently.
  const scrubRaw = clamp01((t - (LOCK + 0.7)) / 3.4);
  const scrub = scrubRaw; // 0→1 across the strip
  const STUDIO_TILES = 5;

  // --- the lock-in: a weighty spring settle on the launch ----------------
  const stamp = springAt(frame, fps, LOCK, SPRING.HEAVY); // 0→1 weighty settle
  const stampScale = mix(1.12, 1, clamp01(stamp)); // slams down to rest
  const flash = clamp01(1 - (t - LOCK) / 0.45) * (t >= LOCK ? 1 : 0);
  const riser = beat(frame, fps, LOCK - 1.4, LOCK, EASE.out); // build into apex
  const ringPulse = 0.5 + 0.5 * osc(t, 3);
  const lockRing = clamp01(stamp);

  // hold→ease orbit so the slab reads the grid filling, then a final arc that
  // settles to centre (0°) right at the launch — the snap-to-camera payoff.
  const legs = [
    { arc: -18, hold: 0.6, travel: 2.6 },
    { arc: 26, hold: 1.2, travel: 2.8 },
    { arc: -8, hold: 0.6, travel: 1.8 }, // lands ~0° near LOCK
  ];

  // deterministic per-tile "kind" so the grid reads like varied assets.
  const tileKind = (i: number) => i % 3; // 0 thumb, 1 wave, 2 chip

  const HeroFace = (
    <div
      style={{
        position: "absolute",
        inset: 0,
        padding: 30,
        display: "flex",
        flexDirection: "column",
        gap: 16,
        transform: `scale(${stampScale})`,
      }}
    >
      {/* the lock ring that snaps tight on the launch beat */}
      <div
        style={{
          position: "absolute",
          inset: 16,
          borderRadius: 24,
          border: `2px solid ${withAlpha(C.accent, 0.3 + 0.45 * ringPulse)}`,
          opacity: lockRing,
          boxShadow: `0 0 30px ${withAlpha(C.accent, 0.3 * ringPulse)}`,
          pointerEvents: "none",
          zIndex: 5,
        }}
      />

      {/* header row — title + GENERATING…/READY status pill */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
        }}
      >
        <div
          style={{
            fontFamily: MONO,
            fontSize: 12,
            letterSpacing: 3,
            color: C.textDim,
            textTransform: "uppercase",
          }}
        >
          render · queue
        </div>
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 8,
            padding: "5px 12px",
            borderRadius: 999,
            background: withAlpha(genDone ? C.accent2 : C.accent, 0.16),
            border: `1px solid ${withAlpha(
              genDone ? C.accent2 : C.accent,
              0.5,
            )}`,
            fontFamily: MONO,
            fontSize: 12,
            letterSpacing: 2,
            color: genDone ? C.accent2 : C.accent,
          }}
        >
          <span
            style={{
              width: 8,
              height: 8,
              borderRadius: "50%",
              background: genDone ? C.accent2 : C.accent,
              boxShadow: `0 0 10px ${C.accentGlow}`,
              opacity: genDone ? 1 : 0.5 + 0.5 * osc(t, 0.9),
            }}
          />
          {genDone ? "READY" : `GENERATING ${genPct}%`}
        </div>
      </div>

      {/* the GRID of asset tiles — fills one-by-one */}
      <div
        style={{
          flex: 1,
          display: "grid",
          gridTemplateColumns: `repeat(${COLS}, 1fr)`,
          gridTemplateRows: `repeat(${ROWS}, 1fr)`,
          gap: 12,
          position: "relative",
        }}
      >
        {Array.from({ length: TILES }, (_, i) => {
          const tAt = GEN_START + i * GEN_STEP;
          const fp = beat(frame, fps, tAt, tAt + GEN_FILL, EASE.backOut);
          const justLit = clamp01(1 - (t - (tAt + GEN_FILL)) / 0.4);
          const kind = tileKind(i);
          return (
            <div
              key={i}
              style={{
                borderRadius: 12,
                position: "relative",
                overflow: "hidden",
                background:
                  fp > 0.02
                    ? `linear-gradient(135deg, ${withAlpha(
                        C.accent2,
                        0.22,
                      )}, ${withAlpha("#0a0e16", 0.9)})`
                    : withAlpha("#0a0e16", 0.5),
                border: `1px solid ${withAlpha(
                  C.accent,
                  0.18 + 0.4 * fp + 0.4 * justLit,
                )}`,
                opacity: mix(0.35, 1, fp),
                transform: `scale(${mix(0.84, 1, fp)})`,
                boxShadow:
                  fp > 0.5
                    ? `0 6px 20px ${withAlpha("#000", 0.5)}, 0 0 ${(
                        18 * justLit
                      ).toFixed(0)}px ${withAlpha(C.accent, 0.4 * justLit)}`
                    : "none",
              }}
            >
              {/* tile content varies by kind to read as varied assets */}
              {kind === 0 && (
                <>
                  <div
                    style={{
                      position: "absolute",
                      left: 8,
                      top: 8,
                      width: 18,
                      height: 18,
                      borderRadius: 5,
                      background: withAlpha(C.accent, 0.55 * fp),
                    }}
                  />
                  <div
                    style={{
                      position: "absolute",
                      left: 8,
                      right: 8,
                      bottom: 8,
                      height: 5,
                      borderRadius: 3,
                      background: withAlpha(C.accent2, 0.7 * fp),
                    }}
                  />
                </>
              )}
              {kind === 1 && (
                <div
                  style={{
                    position: "absolute",
                    inset: 0,
                    display: "flex",
                    alignItems: "flex-end",
                    gap: 4,
                    padding: 10,
                  }}
                >
                  {[0.4, 0.8, 0.55, 0.95, 0.65, 0.85].map((h, b) => (
                    <div
                      key={b}
                      style={{
                        flex: 1,
                        height: `${h * 100 * fp}%`,
                        borderRadius: 2,
                        background: withAlpha(C.accent, 0.5 * fp),
                      }}
                    />
                  ))}
                </div>
              )}
              {kind === 2 && (
                <div
                  style={{
                    position: "absolute",
                    inset: 0,
                    display: "flex",
                    flexDirection: "column",
                    justifyContent: "center",
                    gap: 6,
                    padding: 12,
                  }}
                >
                  <div
                    style={{
                      height: 6,
                      width: `${70 * fp}%`,
                      borderRadius: 3,
                      background: withAlpha(C.accent2, 0.7 * fp),
                    }}
                  />
                  <div
                    style={{
                      height: 6,
                      width: `${45 * fp}%`,
                      borderRadius: 3,
                      background: withAlpha("#ffffff", 0.22 * fp),
                    }}
                  />
                </div>
              )}
              {/* ignition flash as the tile lands */}
              <div
                style={{
                  position: "absolute",
                  inset: 0,
                  background: withAlpha("#ffffff", 0.5 * justLit),
                  mixBlendMode: "screen",
                  pointerEvents: "none",
                }}
              />
            </div>
          );
        })}

        {/* STUDIO PREVIEW overlay — slides up over the grid on launch */}
        <div
          style={{
            position: "absolute",
            inset: 0,
            borderRadius: 14,
            background: `linear-gradient(160deg, ${withAlpha(
              "#0b1018",
              0.96,
            )}, ${withAlpha("#05070c", 0.98)})`,
            border: `1px solid ${withAlpha(C.accent, 0.4)}`,
            opacity: studioOpen,
            transform: `translateY(${mix(34, 0, studioOpen)}px)`,
            display: "flex",
            flexDirection: "column",
            padding: 16,
            gap: 12,
            pointerEvents: "none",
          }}
        >
          {/* studio header — Motion Studio + 13s preview clock */}
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
            }}
          >
            <div
              style={{
                fontFamily: FONT,
                fontWeight: 800,
                fontSize: 18,
                letterSpacing: "-0.01em",
                color: C.text,
              }}
            >
              Motion Studio
            </div>
            <div
              style={{
                fontFamily: MONO,
                fontSize: 12,
                letterSpacing: 2,
                color: C.accent2,
              }}
            >
              {`00:${String(Math.floor(scrub * 13)).padStart(2, "0")} / 00:13`}
            </div>
          </div>

          {/* big preview viewport — the current scene under the play head */}
          <div
            style={{
              flex: 1,
              borderRadius: 10,
              position: "relative",
              overflow: "hidden",
              background: `radial-gradient(120% 120% at 50% 20%, ${withAlpha(
                C.accent,
                0.18,
              )}, ${withAlpha("#06080d", 0.95)})`,
              border: `1px solid ${withAlpha(C.accent, 0.3)}`,
            }}
          >
            <div
              style={{
                position: "absolute",
                left: "50%",
                top: "46%",
                width: 64,
                height: 64,
                transform: "translate(-50%,-50%)",
                borderRadius: "50%",
                background: ACCENT_GRAD,
                boxShadow: `0 0 30px ${C.accentGlow}`,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                opacity: studioOpen,
              }}
            >
              {/* play triangle */}
              <div
                style={{
                  width: 0,
                  height: 0,
                  borderTop: "13px solid transparent",
                  borderBottom: "13px solid transparent",
                  borderLeft: `20px solid #1a0d03`,
                  marginLeft: 5,
                }}
              />
            </div>
          </div>

          {/* thumbnail strip + scrubbing play head */}
          <div style={{ position: "relative", height: 46 }}>
            <div
              style={{
                position: "absolute",
                inset: 0,
                display: "grid",
                gridTemplateColumns: `repeat(${STUDIO_TILES}, 1fr)`,
                gap: 6,
              }}
            >
              {Array.from({ length: STUDIO_TILES }, (_, i) => {
                const active =
                  Math.floor(scrub * STUDIO_TILES) === i ? 1 : 0;
                return (
                  <div
                    key={i}
                    style={{
                      borderRadius: 7,
                      background: `linear-gradient(135deg, ${withAlpha(
                        C.accent2,
                        0.18 + 0.25 * active,
                      )}, ${withAlpha("#0a0e16", 0.92)})`,
                      border: `1px solid ${withAlpha(
                        C.accent,
                        0.25 + 0.5 * active,
                      )}`,
                      boxShadow: active
                        ? `0 0 16px ${withAlpha(C.accent, 0.4)}`
                        : "none",
                    }}
                  />
                );
              })}
            </div>
            {/* the play head line that scrubs across the strip */}
            <div
              style={{
                position: "absolute",
                top: -6,
                bottom: -6,
                left: `${scrub * 100}%`,
                width: 2,
                background: C.text,
                boxShadow: `0 0 12px ${withAlpha("#ffffff", 0.8)}`,
                opacity: studioOpen,
              }}
            >
              <div
                style={{
                  position: "absolute",
                  top: -7,
                  left: "50%",
                  transform: "translateX(-50%) rotate(45deg)",
                  width: 9,
                  height: 9,
                  background: C.text,
                }}
              />
            </div>
          </div>
        </div>
      </div>

      {/* progress bar + LAUNCH MOTION STUDIO button (hidden once studio opens) */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 14,
          opacity: 1 - studioOpen,
        }}
      >
        {/* progress track */}
        <div
          style={{
            flex: 1,
            height: 10,
            borderRadius: 6,
            background: withAlpha("#ffffff", 0.08),
            overflow: "hidden",
            position: "relative",
          }}
        >
          <div
            style={{
              position: "absolute",
              inset: 0,
              width: `${genProg * 100}%`,
              borderRadius: 6,
              background: ACCENT_GRAD,
              boxShadow: `0 0 16px ${C.accentGlow}`,
            }}
          />
        </div>

        {/* launch button — lights up once the grid is full, then is clicked */}
        <div
          style={{
            padding: "11px 22px",
            borderRadius: 12,
            fontFamily: FONT,
            fontWeight: 800,
            fontSize: 17,
            letterSpacing: "0.01em",
            whiteSpace: "nowrap",
            color: btnIn > 0.4 ? "#1a0d03" : C.textDim,
            background:
              btnIn > 0.02
                ? ACCENT_GRAD
                : withAlpha("#ffffff", 0.06),
            border: `1px solid ${withAlpha(C.accent, 0.4 + 0.4 * btnIn)}`,
            boxShadow:
              btnIn > 0.4
                ? `0 0 ${(22 + 14 * btnGlow).toFixed(
                    0,
                  )}px ${withAlpha(C.accent, 0.45 * btnGlow)}`
                : "none",
            opacity: mix(0.5, 1, btnIn),
            transform: `scale(${mix(0.94, 1, btnIn) * pressScale})`,
          }}
        >
          Launch Motion Studio
        </div>
      </div>
    </div>
  );

  return (
    <Plinth>
      <Eyebrow at={0.3}>Generate · Preview</Eyebrow>

      {/* riser glow swelling behind the hero into the launch */}
      <AbsoluteFill style={{ pointerEvents: "none", zIndex: 1 }}>
        <GlowPulse
          size={1000}
          color={withAlpha(C.accent, 0.1 * riser)}
          strength={riser}
        />
      </AbsoluteFill>

      {/* impact flash + shockwave on the launch payoff */}
      <AbsoluteFill style={{ pointerEvents: "none", zIndex: 6 }}>
        <GlowPulse
          size={1200}
          color={withAlpha(C.accent, 0.2 * flash)}
          strength={flash}
        />
        <Shockwave at={LOCK} size={820} />
        <Shockwave at={LOCK + 0.08} size={1120} />
        <LightSweep at={LOCK} dur={1.0} strength={0.16} />
      </AbsoluteFill>

      <OrbitWorld legs={legs} perspective={2300} bobAmp={12}>
        <DustMotes layers={3} opacity={0.42} />

        <Extrude w={820} h={500} depth={22} layers={16} radius={28}>
          {HeroFace}
        </Extrude>

        {/* billboarded spec callouts firing at orbit waypoints */}
        <Callout
          title="The Render"
          value="GENERATING…"
          at={fps * 2.2}
          x={0}
          y={-330}
          leader={120}
          side="right"
        />
        <Callout
          title="12 Assets"
          value="FILLED IN"
          at={fps * 5.0}
          x={490}
          y={150}
          leader={150}
          side="right"
        />
        <Callout
          title="One Click"
          value="LAUNCH STUDIO"
          at={fps * (LOCK + 0.3)}
          x={-500}
          y={130}
          leader={160}
          side="left"
        />
        <Callout
          title="Live Preview"
          value="13s PREVIEW"
          at={fps * (LOCK + 1.6)}
          x={0}
          y={340}
          leader={120}
          side="right"
        />
      </OrbitWorld>

      {/* flat masked mirror sibling — re-renders the hero, simplified & matte */}
      <Plinth.Reflection>
        <Extrude w={820} h={500} depth={22} layers={10} radius={28} sheen={false}>
          {HeroFace}
        </Extrude>
      </Plinth.Reflection>
    </Plinth>
  );
};

export default MgOrbitScene15Generate;