import React from "react";
import { AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
import { useJobDesign, type DesignMotion } from "../job/script";

// Scene entry/exit timing per motion-energy role.
const ENERGY_FADES = {
  calm: { in: [0, 15], out: [-14, 0] },
  steady: { in: [0, 9], out: [-7, 0] },
  energetic: { in: [0, 5], out: [-4, 0] },
} as const;

const CLAMP = {
  extrapolateLeft: "clamp",
  extrapolateRight: "clamp",
} as const;

interface Entrance {
  opacity: number;
  transform: string;
  filter?: string;
}

/**
 * Per-scene entrance animation, chosen by the AI in the scene's `design`.
 * All variants are deterministic (frame-based) so renders are reproducible.
 */
function entrance(motion: DesignMotion, frame: number, fps: number): Entrance {
  switch (motion) {
    case "pop": {
      const p = spring({
        frame: Math.max(0, frame),
        fps,
        config: { damping: 12, mass: 0.75, stiffness: 150 },
      });
      return {
        opacity: Math.min(1, p * 1.6),
        transform: `scale(${0.86 + p * 0.14})`,
      };
    }
    case "slide-left": {
      const f = interpolate(frame, [0, 14], [0, 1], CLAMP);
      return { opacity: f, transform: `translateX(${(1 - f) * 180}px)` };
    }
    case "slide-right": {
      const f = interpolate(frame, [0, 14], [0, 1], CLAMP);
      return { opacity: f, transform: `translateX(${(1 - f) * -180}px)` };
    }
    case "zoom": {
      const f = interpolate(frame, [0, 18], [0, 1], CLAMP);
      return {
        opacity: f,
        transform: `scale(${1.14 - f * 0.14})`,
      };
    }
    case "blur": {
      const f = interpolate(frame, [0, 16], [0, 1], CLAMP);
      return {
        opacity: f,
        filter: `blur(${(1 - f) * 18}px)`,
        transform: `translateY(${(1 - f) * 20}px)`,
      };
    }
    // "fade-up" — the classic editorial rise
    default: {
      const f = interpolate(frame, [0, 14], [0, 1], CLAMP);
      return { opacity: f, transform: `translateY(${(1 - f) * 54}px)` };
    }
  }
}

export const SceneShell: React.FC<{
  children: React.ReactNode;
  /** AI-authored entrance motion (scene design). Defaults to fade-up. */
  motion?: DesignMotion;
}> = ({ children, motion = "fade-up" }) => {
  const frame = useCurrentFrame();
  const { durationInFrames, fps } = useVideoConfig();
  const design = useJobDesign();
  const fades = ENERGY_FADES[design?.energy ?? "steady"];
  const inOp = interpolate(frame, fades.in, [0, 1], CLAMP);
  const outOp = interpolate(
    frame,
    [durationInFrames + fades.out[0], durationInFrames + fades.out[1]],
    [1, 0],
    CLAMP
  );
  const enter = entrance(motion, frame, fps);
  return (
    <AbsoluteFill
      style={{
        opacity: inOp * outOp * enter.opacity,
        transform: enter.transform,
        filter: enter.filter,
      }}
    >
      {children}
    </AbsoluteFill>
  );
};
