/**
 * MainComp.tsx - Main Remotion composition with Ken Burns effect
 * 
 * Supports three scene types:
 * 1. kinetic: Text animation (Sequence-based)
 * 2. screenshot: Image with Ken Burns pan/zoom effect
 * 3. caption: Text overlay on current scene
 * 
 * VideoConfig: 1920x1080, 60 fps
 */

import React, { useMemo } from 'react';
import {
  Composition,
  Sequence,
  interpolate,
  useCurrentFrame,
  useVideoConfig,
  AbsoluteFill,
  Img,
  staticFile,
} from 'remotion';
import { Scene, KineticScene, ScreenshotScene, CaptionScene } from '../types/Scene';

// VideoConfig constants
export const VIDEO_WIDTH = 1920;
export const VIDEO_HEIGHT = 1080;
export const VIDEO_FPS = 60;

/**
 * Converts duration in seconds to frame count at 60 fps
 */
const secondsToFrames = (seconds: number, fps: number = VIDEO_FPS): number => {
  return Math.ceil(seconds * fps);
};

/**
 * Ken Burns Effect Component
 * Applies subtle zoom and pan animation to an image
 * - Starts at scale 1.0, ends at scale 1.05 (5% zoom)
 * - Vertical pan: 0 to full height (creates movement illusion)
 */
interface KenBurnsProps {
  imagePath: string;
  alt?: string;
  duration: number; // in frames
}

const KenBurnsImage: React.FC<KenBurnsProps> = ({ imagePath, alt = 'Scene', duration }) => {
  const frame = useCurrentFrame();
  
  // Scale interpolation: 1.0 → 1.05
  const scale = interpolate(frame, [0, duration], [1.0, 1.05]);
  
  // Vertical pan: 0 → full height (in pixels)
  const translateY = interpolate(frame, [0, duration], [0, VIDEO_HEIGHT * 0.08]);
  
  return (
    <AbsoluteFill
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        overflow: 'hidden',
        backgroundColor: '#000',
      }}
    >
      <Img
        src={imagePath}
        style={{
          width: VIDEO_WIDTH,
          height: VIDEO_HEIGHT,
          objectFit: 'cover',
          transform: `scale(${scale}) translateY(${-translateY}px)`,
          transformOrigin: 'center center',
        }}
        alt={alt}
      />
    </AbsoluteFill>
  );
};

/**
 * Kinetic Scene Component - Text animation
 */
interface KineticSceneComponentProps {
  scene: KineticScene;
  duration: number; // in frames
}

const KineticSceneComponent: React.FC<KineticSceneComponentProps> = ({
  scene,
  duration,
}) => {
  const frame = useCurrentFrame();
  
  // Fade in and scale effect
  const opacity = interpolate(frame, [0, duration * 0.1], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });
  
  const scale = interpolate(frame, [0, duration * 0.15], [0.8, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  return (
    <AbsoluteFill
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: scene.backgroundColor || '#1e1e2e',
        fontFamily: scene.fontFamily || 'Arial, sans-serif',
      }}
    >
      <div
        style={{
          opacity,
          transform: `scale(${scale})`,
          textAlign: 'center',
          color: scene.color || '#ffffff',
          fontSize: scene.fontSize || 64,
          fontWeight: 'bold',
          maxWidth: '90%',
          padding: '40px',
        }}
      >
        {scene.text}
      </div>
    </AbsoluteFill>
  );
};

/**
 * Caption Overlay Component
 */
interface CaptionComponentProps {
  scene: CaptionScene;
  duration: number; // in frames
}

const CaptionComponent: React.FC<CaptionComponentProps> = ({ scene, duration }) => {
  const frame = useCurrentFrame();
  
  // Fade in/out effect
  const opacity = interpolate(frame, [0, duration * 0.2, duration * 0.8, duration], [0, 1, 1, 0], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  const positionMap = {
    top: '5%',
    middle: '50%',
    bottom: '85%',
  };

  const topPosition = positionMap[scene.position || 'bottom'];

  return (
    <AbsoluteFill>
      <div
        style={{
          position: 'absolute',
          top: topPosition,
          left: '5%',
          right: '5%',
          transform: 'translateY(-50%)',
          opacity,
          backgroundColor: scene.backgroundColor || 'rgba(0, 0, 0, 0.6)',
          color: scene.color || '#ffffff',
          fontSize: scene.fontSize || 36,
          fontFamily: scene.fontFamily || 'Arial, sans-serif',
          padding: '20px 30px',
          borderRadius: '8px',
          textAlign: 'center',
          maxWidth: '90%',
          margin: '0 auto',
        }}
      >
        {scene.text}
      </div>
    </AbsoluteFill>
  );
};

/**
 * Main Composition - orchestrates all scenes
 */
interface MainCompProps {
  scenes: Scene[];
}

const MainComp: React.FC<MainCompProps> = ({ scenes }) => {
  const { durationInFrames } = useVideoConfig();
  
  // Calculate cumulative frame positions
  const sequenceLayout = useMemo(() => {
    let currentFrame = 0;
    return scenes.map((scene) => {
      const frameDuration = secondsToFrames(scene.duration);
      const fromFrame = currentFrame;
      currentFrame += frameDuration;
      return { scene, fromFrame, frameDuration };
    });
  }, [scenes]);

  return (
    <AbsoluteFill style={{ backgroundColor: '#000' }}>
      {sequenceLayout.map(({ scene, fromFrame, frameDuration }) => {
        return (
          <Sequence key={scene.id} from={fromFrame} durationInFrames={frameDuration}>
            {scene.type === 'kinetic' && (
              <KineticSceneComponent
                scene={scene as KineticScene}
                duration={frameDuration}
              />
            )}
            {scene.type === 'screenshot' && (
              <KenBurnsImage
                imagePath={(scene as ScreenshotScene).imagePath}
                alt={(scene as ScreenshotScene).alt}
                duration={frameDuration}
              />
            )}
            {scene.type === 'caption' && (
              <CaptionComponent
                scene={scene as CaptionScene}
                duration={frameDuration}
              />
            )}
          </Sequence>
        );
      })}
    </AbsoluteFill>
  );
};

/**
 * Example usage with sample scenes
 */
const exampleScenes: Scene[] = [
  {
    id: 'intro',
    type: 'kinetic',
    text: 'Welcome to Video Magic',
    duration: 3,
    fontSize: 72,
    color: '#ffffff',
    backgroundColor: '#1e1e2e',
  },
  {
    id: 'screenshot-1',
    type: 'screenshot',
    imagePath: staticFile('sample.jpg'),
    duration: 5,
    alt: 'Sample Screenshot',
  },
  {
    id: 'caption-1',
    type: 'caption',
    text: 'Amazing Ken Burns Effect Applied',
    duration: 5,
    fontSize: 48,
    color: '#ffffff',
    position: 'bottom',
  },
  {
    id: 'outro',
    type: 'kinetic',
    text: 'Thank You!',
    duration: 2,
    fontSize: 64,
    color: '#00ff00',
    backgroundColor: '#000000',
  },
];

// Calculate total duration from scenes
const getTotalDurationFrames = (scenes: Scene[]): number => {
  return scenes.reduce((total, scene) => total + secondsToFrames(scene.duration), 0);
};

export default MainComp;

/**
 * Composition registration configuration
 */
export const mainCompositionConfig = {
  id: 'MainComp',
  component: () => <MainComp scenes={exampleScenes} />,
  durationInFrames: getTotalDurationFrames(exampleScenes),
  fps: VIDEO_FPS,
  width: VIDEO_WIDTH,
  height: VIDEO_HEIGHT,
};

// Export helper hook for custom compositions
export const useMainCompConfig = (scenes: Scene[]) => ({
  id: 'MainComp',
  component: () => <MainComp scenes={scenes} />,
  durationInFrames: getTotalDurationFrames(scenes),
  fps: VIDEO_FPS,
  width: VIDEO_WIDTH,
  height: VIDEO_HEIGHT,
});
