/**
 * PitchVideo Composition
 *
 * Main composition that renders pitch video blocks in sequence.
 * Each block has its own MP3 audio and duration.
 */

import React from 'react';
import { AbsoluteFill, Audio, Sequence, interpolate, staticFile, useVideoConfig } from 'remotion';
import { SlideScene } from '../scenes/SlideScene';
import { StatScene } from '../scenes/StatScene';
import { ProblemScene } from '../scenes/ProblemScene';
import { FeatureScene } from '../scenes/FeatureScene';
import { AppDemoScene } from '../scenes/AppDemoScene';
import { ClosingScene } from '../scenes/ClosingScene';
import { msToFrames } from '../lib/timing';
import { stemedbPalette } from '../lib/colors';
import type { PitchBlock, PitchScript } from '../types/pitch-script';

type Props = {
  script: PitchScript;
};

export const PitchVideo: React.FC<Props> = ({ script }) => {
  const { fps, durationInFrames } = useVideoConfig();

  // Calculate cumulative start times for each block
  const blockStarts: number[] = [];
  let cumulativeMs = 0;
  for (const block of script.blocks) {
    blockStarts.push(cumulativeMs);
    cumulativeMs += block.audio.durationMs;
  }

  const renderBlock = (block: PitchBlock, index: number) => {
    const startMs = blockStarts[index];
    const startFrame = msToFrames(startMs, fps);
    const durationFrames = msToFrames(block.audio.durationMs, fps);

    const content = block.content;

    let sceneElement: React.ReactNode = null;

    switch (content.type) {
      case 'slide':
        sceneElement = <SlideScene content={content} audio={block.audio} />;
        break;

      case 'stat':
        sceneElement = <StatScene content={content} />;
        break;

      case 'problem':
        sceneElement = <ProblemScene content={content} />;
        break;

      case 'feature':
        sceneElement = <FeatureScene content={content} />;
        break;

      case 'app-demo':
        sceneElement = <AppDemoScene content={content} />;
        break;

      case 'closing':
        sceneElement = <ClosingScene content={content} />;
        break;

      default:
        return null;
    }

    return (
      <Sequence
        key={block.id}
        from={startFrame}
        durationInFrames={durationFrames}
        name={`${block.type}: ${block.id}`}
      >
        {sceneElement}

        {/* Per-block audio */}
        <Audio src={staticFile(block.audio.src)} />
      </Sequence>
    );
  };

  // Music volume with fade in/out
  const musicVolume = React.useCallback(
    (frame: number) => {
      const { music } = script;
      if (!music) return 0;

      const fadeInFrames = msToFrames(music.fadeInMs, fps);
      const fadeOutFrames = msToFrames(music.fadeOutMs, fps);

      return interpolate(
        frame,
        [0, fadeInFrames, durationInFrames - fadeOutFrames, durationInFrames],
        [0, music.volume, music.volume, 0],
        { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
      );
    },
    [script.music, fps, durationInFrames]
  );

  return (
    <AbsoluteFill style={{ backgroundColor: stemedbPalette.background }}>
      {script.blocks.map(renderBlock)}

      {/* Background music */}
      {script.music?.src && (
        <Audio src={staticFile(script.music.src)} volume={musicVolume} />
      )}
    </AbsoluteFill>
  );
};
