import React from "react";
import {
  AbsoluteFill,
  Sequence,
  Video,
  interpolate,
  useCurrentFrame,
  useVideoConfig,
} from "remotion";
import { ColibriScene } from "../../schemas/manifest.js";
import { COLIBRI, brandGradient } from "./tokens.js";

type Palette = { primary: string; secondary: string; accent: string };

export function sceneDurationFrames(scene: ColibriScene, fps: number): number {
  return Math.max(1, Math.round((scene.duration_seconds ?? 5) * fps));
}

export const FadeInText: React.FC<{
  title: string;
  subtitle?: string;
  palette: Palette;
  align?: "center" | "left";
  titleSize?: number;
}> = ({ title, subtitle, palette, align = "center", titleSize = 72 }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const opacity = interpolate(frame, [0, fps * 0.35], [0, 1], {
    extrapolateRight: "clamp",
  });
  const translateY = interpolate(frame, [0, fps * 0.35], [20, 0], {
    extrapolateRight: "clamp",
  });

  return (
    <div
      style={{
        opacity,
        transform: `translateY(${translateY}px)`,
        textAlign: align,
        maxWidth: align === "center" ? 1200 : 900,
      }}
    >
      <div
        style={{
          fontSize: titleSize,
          fontWeight: 500,
          lineHeight: 1.05,
          marginBottom: subtitle ? 20 : 0,
          fontFamily: COLIBRI.fontDisplay,
          color: COLIBRI.text1,
        }}
      >
        {title}
      </div>
      {subtitle ? (
        <div
          style={{
            fontSize: 28,
            opacity: 0.88,
            lineHeight: 1.4,
            fontFamily: COLIBRI.fontBody,
            color: COLIBRI.text2,
          }}
        >
          {subtitle}
        </div>
      ) : null}
    </div>
  );
};

export const GradientScene: React.FC<{
  title: string;
  subtitle?: string;
  palette: Palette;
  titleSize?: number;
}> = ({ title, subtitle, palette, titleSize }) => (
  <AbsoluteFill
    style={{
      background: brandGradient(palette.primary, palette.secondary, palette.accent),
      justifyContent: "center",
      alignItems: "center",
      padding: 96,
    }}
  >
    <FadeInText
      title={title}
      subtitle={subtitle}
      palette={palette}
      titleSize={titleSize}
    />
  </AbsoluteFill>
);

export const BrollScene: React.FC<{
  brollFile: string;
  title: string;
  subtitle?: string;
  palette: Palette;
  overlayStrength?: number;
}> = ({ brollFile, title, subtitle, palette, overlayStrength = 0.55 }) => (
  <AbsoluteFill>
    <Video
      src={brollFile}
      style={{ width: "100%", height: "100%", objectFit: "cover" }}
    />
    <AbsoluteFill
      style={{
        background: `linear-gradient(180deg, rgba(8,6,26,0.15) 0%, rgba(8,6,26,${overlayStrength}) 100%)`,
      }}
    />
    <AbsoluteFill
      style={{ justifyContent: "center", alignItems: "center", padding: 96 }}
    >
      <FadeInText title={title} subtitle={subtitle} palette={palette} />
    </AbsoluteFill>
  </AbsoluteFill>
);

export const SceneSequence: React.FC<{
  scenes: ColibriScene[];
  palette: Palette;
  brollFiles?: Record<string, string>;
  renderScene?: (
    scene: ColibriScene,
    index: number,
    sceneId: string,
    brollFile?: string,
  ) => React.ReactNode;
}> = ({ scenes, palette, brollFiles = {}, renderScene }) => {
  const { fps } = useVideoConfig();
  let cursor = 0;

  return (
    <>
      {scenes.map((scene, index) => {
        const durationInFrames = sceneDurationFrames(scene, fps);
        const from = cursor;
        cursor += durationInFrames;
        const sceneId = scene.id ?? String(index + 1);
        const brollFile = brollFiles[sceneId];
        const title = scene.on_screen_text ?? "";
        const subtitle = scene.visual_direction ?? scene.narration;

        const content =
          renderScene?.(scene, index, sceneId, brollFile) ??
          (brollFile ? (
            <BrollScene
              brollFile={brollFile}
              title={title}
              subtitle={subtitle}
              palette={palette}
            />
          ) : (
            <GradientScene title={title} subtitle={subtitle} palette={palette} />
          ));

        return (
          <Sequence
            key={`${sceneId}-${index}`}
            from={from}
            durationInFrames={durationInFrames}
          >
            {content}
          </Sequence>
        );
      })}
    </>
  );
};

export function totalSceneFrames(scenes: ColibriScene[], fps: number): number {
  return scenes.reduce((sum, scene) => sum + sceneDurationFrames(scene, fps), 0);
}
