// @ts-nocheck
// ============================================================================
// MOTION GRAPHICS · OBSIDIAN ORBIT — Scene 08 / CREATE EPISODE  (13s, 390f)
//
// "Keynote object-worship". ONE hero artifact: a DASHBOARD slab. A thick glass
// slab whose face is a project dashboard — a glowing "+ Create Episode" button
// gets clicked (a ripple fires), a name field TYPES a title, then a back-end
// directory SKELETON self-assembles row by row on the face. Instant scaffolding,
// keynote calm. The WORLD orbits (never the camera) in slow hold->ease arcs;
// spec Callouts billboard on drawn leader lines at waypoints ("+ CREATE EPISODE",
// "AUTO-SCAFFOLD"); the angle-tracked sheen rakes the turn; a gentle settle on
// the payoff as the tree finishes locking in.
//
// 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";
import { TypeOn } from "../../chronixel/viz/text";

/* ----------------------------------------------------------------------------
   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>
  );
};

/* ============================================================================
   CREATE EPISODE.  Hero = the DASHBOARD artifact. A glass slab whose face is a
   project dashboard: a glowing "+ Create Episode" button is clicked (ripple),
   a name field types a title, then a directory skeleton self-assembles. The
   world orbits in, callouts fire, and the scaffold locks in on the payoff.
   ========================================================================== */
export const MgOrbitScene08CreateEpisode: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const t = frame / fps;

  // --- beat timeline (seconds) -------------------------------------------
  const CLICK = 2.4; // the "+ Create Episode" button is pressed (ripple)
  const TYPE = 3.0; // the name field begins typing the title
  const SCAFFOLD = 5.6; // the directory skeleton starts self-assembling
  const LOCK = 9.0; // the scaffold finishes — a calm settle payoff

  // --- face choreography -------------------------------------------------
  const dashIn = beat(frame, fps, 0.8, 2.0, EASE.out); // dashboard fades up
  const btnGlow = 0.5 + 0.5 * osc(t, 1.4); // the create button breathes
  const pressDip = 1 - 0.06 * clamp01(1 - Math.abs(t - CLICK) / 0.18); // squash
  const ripple = clamp01((t - CLICK) / 0.7); // click ripple expands
  const rippleLife = clamp01(1 - (t - CLICK) / 0.7);

  // the name field appears right after the click, then the title types in.
  const fieldP = beat(frame, fps, CLICK + 0.15, CLICK + 0.6, EASE.backOut);

  // the directory tree rows assemble one at a time after SCAFFOLD.
  const tree = [
    { label: "episode-08/", depth: 0 },
    { label: "scenes/", depth: 1 },
    { label: "scene-01.tsx", depth: 2 },
    { label: "scene-02.tsx", depth: 2 },
    { label: "assets/", depth: 1 },
    { label: "render.config.ts", depth: 1 },
  ];

  // --- the lock-in: a gentle, weighty settle on the payoff ----------------
  const stamp = springAt(frame, fps, LOCK, SPRING.HEAVY); // 0->1 settle
  const stampScale = mix(1.04, 1, clamp01(stamp)); // a soft, calm seat
  const flash = clamp01(1 - (t - LOCK) / 0.5) * (t >= LOCK ? 1 : 0);
  const riser = beat(frame, fps, LOCK - 1.4, LOCK, EASE.out); // build into apex
  const lockRing = clamp01(stamp);
  const ringPulse = 0.5 + 0.5 * osc(t, 3);

  // hold->ease orbit: shows the button face on the way in, turns to reveal the
  // scaffolding, then a final short arc that settles to centre (0°) at the lock.
  const legs = [
    { arc: -18, hold: 0.7, travel: 2.4 }, // ease left to read the button
    { arc: 26, hold: 1.6, travel: 2.8 }, // swing across as it types/scaffolds
    { arc: -8, hold: 0.6, travel: 1.8 }, // lands ~0° near LOCK — settle
  ];

  const HeroFace = (
    <div
      style={{
        position: "absolute",
        inset: 0,
        padding: 30,
        display: "flex",
        flexDirection: "column",
        gap: 16,
        transform: `scale(${stampScale})`,
        opacity: dashIn,
      }}
    >
      {/* dashboard chrome — title bar */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 10,
          paddingBottom: 14,
          borderBottom: `1px solid ${C.glassBorder}`,
        }}
      >
        <div
          style={{
            width: 10,
            height: 10,
            borderRadius: "50%",
            background: withAlpha(C.accent, 0.85),
            boxShadow: `0 0 10px ${C.accentGlow}`,
          }}
        />
        <div
          style={{
            fontFamily: MONO,
            fontSize: 12,
            letterSpacing: 3,
            textTransform: "uppercase",
            color: C.textDim,
          }}
        >
          chronixel · dashboard
        </div>
        <div style={{ flex: 1 }} />
        <div
          style={{
            fontFamily: MONO,
            fontSize: 11,
            letterSpacing: 2,
            color: withAlpha(C.accent2, 0.7),
          }}
        >
          new project
        </div>
      </div>

      {/* main body: left = create + name field, right = scaffold tree */}
      <div
        style={{
          flex: 1,
          display: "grid",
          gridTemplateColumns: "1fr 1fr",
          gap: 22,
          alignItems: "stretch",
        }}
      >
        {/* LEFT — the glowing "+ Create Episode" button + the name field */}
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",
            gap: 18,
          }}
        >
          {/* the create button (with click ripple) */}
          <div
            style={{
              position: "relative",
              alignSelf: "flex-start",
              display: "flex",
              alignItems: "center",
              gap: 12,
              padding: "16px 26px",
              borderRadius: 16,
              background: ACCENT_GRAD,
              transform: `scale(${pressDip})`,
              boxShadow: `0 8px 30px ${withAlpha(
                C.accent,
                0.4 + 0.25 * btnGlow,
              )}, inset 0 1px 0 ${withAlpha("#ffffff", 0.4)}`,
              overflow: "hidden",
            }}
          >
            <span
              style={{
                fontFamily: FONT,
                fontWeight: 800,
                fontSize: 30,
                color: "#1a0d03",
                lineHeight: 1,
              }}
            >
              +
            </span>
            <span
              style={{
                fontFamily: FONT,
                fontWeight: 800,
                fontSize: 24,
                color: "#1a0d03",
                letterSpacing: "-0.01em",
                lineHeight: 1,
              }}
            >
              Create Episode
            </span>
            {/* click ripple emanating from the press point */}
            {t >= CLICK && (
              <div
                style={{
                  position: "absolute",
                  left: "50%",
                  top: "50%",
                  width: 40,
                  height: 40,
                  marginLeft: -20,
                  marginTop: -20,
                  borderRadius: "50%",
                  border: `2px solid ${withAlpha("#ffffff", 0.7)}`,
                  transform: `scale(${mix(0.4, 6, ripple)})`,
                  opacity: rippleLife * 0.8,
                  pointerEvents: "none",
                }}
              />
            )}
          </div>

          {/* the name field that types the episode title */}
          <div
            style={{
              opacity: fieldP,
              transform: `translateY(${(1 - fieldP) * 12}px)`,
            }}
          >
            <div
              style={{
                fontFamily: MONO,
                fontSize: 10,
                letterSpacing: 3,
                textTransform: "uppercase",
                color: C.textDim,
                marginBottom: 8,
              }}
            >
              episode name
            </div>
            <div
              style={{
                padding: "12px 16px",
                borderRadius: 12,
                background: withAlpha("#0a0e16", 0.75),
                border: `1px solid ${withAlpha(C.accent, 0.45)}`,
                boxShadow: `inset 0 0 16px ${withAlpha("#000", 0.5)}`,
                minHeight: 26,
                display: "flex",
                alignItems: "center",
              }}
            >
              <TypeOn
                text="Motion Graphics — Pilot"
                at={TYPE}
                cps={16}
                size={20}
                mono={false}
                color={C.text}
                caret
              />
            </div>
          </div>
        </div>

        {/* RIGHT — the back-end directory skeleton self-assembling */}
        <div
          style={{
            position: "relative",
            borderRadius: 14,
            padding: "18px 18px",
            background: withAlpha("#0a0e16", 0.6),
            border: `1px solid ${C.glassBorder}`,
            display: "flex",
            flexDirection: "column",
            gap: 11,
            justifyContent: "center",
          }}
        >
          <div
            style={{
              fontFamily: MONO,
              fontSize: 10,
              letterSpacing: 3,
              textTransform: "uppercase",
              color: withAlpha(C.accent2, 0.7),
              marginBottom: 4,
            }}
          >
            scaffolding
          </div>
          {tree.map((row, i) => {
            const rp = beat(
              frame,
              fps,
              SCAFFOLD + i * 0.28,
              SCAFFOLD + i * 0.28 + 0.5,
              EASE.backOut,
            );
            const isDir = row.label.endsWith("/");
            return (
              <div
                key={i}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 10,
                  marginLeft: row.depth * 22,
                  opacity: rp,
                  transform: `translateX(${(1 - rp) * -14}px)`,
                }}
              >
                {/* node glyph: folder vs file */}
                <div
                  style={{
                    width: 14,
                    height: 11,
                    borderRadius: 3,
                    flexShrink: 0,
                    background: isDir
                      ? withAlpha(C.accent, 0.55)
                      : "transparent",
                    border: isDir
                      ? "none"
                      : `1.5px solid ${withAlpha(C.accent2, 0.7)}`,
                    boxShadow: isDir
                      ? `0 0 8px ${withAlpha(C.accent, 0.5)}`
                      : "none",
                  }}
                />
                <div
                  style={{
                    fontFamily: MONO,
                    fontSize: 15,
                    color: isDir ? C.text : withAlpha(C.text, 0.7),
                    letterSpacing: 0.5,
                  }}
                >
                  {row.label}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* lock ring that snaps tight as the scaffold finishes (calm settle) */}
      <div
        style={{
          position: "absolute",
          inset: 16,
          borderRadius: 24,
          border: `2px solid ${withAlpha(C.accent, 0.25 + 0.4 * ringPulse)}`,
          opacity: lockRing,
          boxShadow: `0 0 28px ${withAlpha(C.accent, 0.28 * ringPulse)}`,
          pointerEvents: "none",
        }}
      />
    </div>
  );

  return (
    <Plinth>
      <Eyebrow at={0.3}>One Click To Scaffold</Eyebrow>

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

      {/* a soft flash + shockwave the instant the button is clicked */}
      <AbsoluteFill style={{ pointerEvents: "none", zIndex: 6 }}>
        <GlowPulse
          size={900}
          color={withAlpha(C.accent2, 0.14 * rippleLife)}
          strength={rippleLife}
        />
        <Shockwave at={CLICK} size={620} />
      </AbsoluteFill>

      {/* a gentle settle flash as the scaffold locks in on the payoff */}
      <AbsoluteFill style={{ pointerEvents: "none", zIndex: 6 }}>
        <GlowPulse
          size={1200}
          color={withAlpha(C.accent, 0.14 * flash)}
          strength={flash}
        />
        <Shockwave at={LOCK} size={780} />
        <LightSweep at={LOCK} dur={1.1} strength={0.13} />
      </AbsoluteFill>

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

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

        {/* billboarded spec callouts firing at orbit waypoints */}
        <Callout
          title="The Trigger"
          value="+ CREATE EPISODE"
          at={fps * CLICK}
          x={0}
          y={-310}
          leader={120}
          side="right"
        />
        <Callout
          title="Instant"
          value="AUTO-SCAFFOLD"
          at={fps * (SCAFFOLD + 0.4)}
          x={490}
          y={140}
          leader={150}
          side="right"
        />
        <Callout
          title="Zero Setup"
          value="READY TO BUILD"
          at={fps * (LOCK + 0.3)}
          x={-490}
          y={150}
          leader={160}
          side="left"
        />
      </OrbitWorld>

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

export default MgOrbitScene08CreateEpisode;