import React from "react";
import {
  AbsoluteFill,
  interpolate,
  useCurrentFrame,
  useVideoConfig,
  spring,
} from "remotion";
import { Scene as SceneType } from "../lib/types";

interface SceneProps {
  scene: SceneType;
}

export const SceneComponent: React.FC<SceneProps> = ({ scene }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const totalFrames = scene.durationInSeconds * fps;

  // Entrance animation (first 20% of scene)
  const entranceDuration = Math.floor(totalFrames * 0.2);
  // Exit animation (last 20% of scene)
  const exitStart = totalFrames - Math.floor(totalFrames * 0.2);

  // Calculate entrance opacity and transform
  const getEntranceStyles = (): React.CSSProperties => {
    const progress = Math.min(frame / entranceDuration, 1);
    const springProgress = spring({
      frame: Math.min(frame, entranceDuration),
      fps,
      config: { damping: 15, stiffness: 100, mass: 0.8 },
    });

    switch (scene.animation.entrance) {
      case "fadeIn":
        return { opacity: interpolate(frame, [0, entranceDuration], [0, 1], { extrapolateRight: "clamp" }) };
      case "slideUp":
        return {
          opacity: interpolate(frame, [0, entranceDuration * 0.5], [0, 1], { extrapolateRight: "clamp" }),
          transform: `translateY(${interpolate(springProgress, [0, 1], [80, 0])}px)`,
        };
      case "slideLeft":
        return {
          opacity: interpolate(frame, [0, entranceDuration * 0.5], [0, 1], { extrapolateRight: "clamp" }),
          transform: `translateX(${interpolate(springProgress, [0, 1], [100, 0])}px)`,
        };
      case "slideRight":
        return {
          opacity: interpolate(frame, [0, entranceDuration * 0.5], [0, 1], { extrapolateRight: "clamp" }),
          transform: `translateX(${interpolate(springProgress, [0, 1], [-100, 0])}px)`,
        };
      case "zoomIn":
        return {
          opacity: interpolate(frame, [0, entranceDuration * 0.5], [0, 1], { extrapolateRight: "clamp" }),
          transform: `scale(${interpolate(springProgress, [0, 1], [0.5, 1])})`,
        };
      case "typewriter":
        return { opacity: 1 };
      case "none":
      default:
        return { opacity: 1 };
    }
  };

  // Calculate exit styles
  const getExitStyles = (): React.CSSProperties => {
    if (frame < exitStart) return {};

    const exitProgress = (frame - exitStart) / (totalFrames - exitStart);

    switch (scene.animation.exit) {
      case "fadeOut":
        return { opacity: interpolate(exitProgress, [0, 1], [1, 0]) };
      case "slideDown":
        return {
          opacity: interpolate(exitProgress, [0.5, 1], [1, 0], { extrapolateLeft: "clamp" }),
          transform: `translateY(${interpolate(exitProgress, [0, 1], [0, 80])}px)`,
        };
      case "slideLeft":
        return {
          opacity: interpolate(exitProgress, [0.5, 1], [1, 0], { extrapolateLeft: "clamp" }),
          transform: `translateX(${interpolate(exitProgress, [0, 1], [0, -100])}px)`,
        };
      case "slideRight":
        return {
          opacity: interpolate(exitProgress, [0.5, 1], [1, 0], { extrapolateLeft: "clamp" }),
          transform: `translateX(${interpolate(exitProgress, [0, 1], [0, 100])}px)`,
        };
      case "zoomOut":
        return {
          opacity: interpolate(exitProgress, [0.5, 1], [1, 0], { extrapolateLeft: "clamp" }),
          transform: `scale(${interpolate(exitProgress, [0, 1], [1, 1.5])})`,
        };
      case "none":
      default:
        return {};
    }
  };

  // Typewriter effect for text
  const getDisplayText = (text: string): string => {
    if (scene.animation.entrance !== "typewriter") return text;
    const charsToShow = Math.floor(
      interpolate(frame, [0, entranceDuration * 1.5], [0, text.length], {
        extrapolateRight: "clamp",
      })
    );
    return text.slice(0, charsToShow);
  };

  // Background
  const backgroundStyle: React.CSSProperties = scene.backgroundGradient
    ? {
        background: `linear-gradient(${scene.backgroundGradient.direction}, ${scene.backgroundGradient.from}, ${scene.backgroundGradient.to})`,
      }
    : {
        backgroundColor: scene.style.backgroundColor,
      };

  const entranceStyles = getEntranceStyles();
  const exitStyles = getExitStyles();

  // Merge entrance and exit
  const combinedStyles: React.CSSProperties = {
    ...entranceStyles,
    ...(frame >= exitStart ? exitStyles : {}),
  };

  // Subtle background animation
  const bgScale = interpolate(frame, [0, totalFrames], [1, 1.05], {
    extrapolateRight: "clamp",
  });

  return (
    <AbsoluteFill
      style={{
        ...backgroundStyle,
        transform: `scale(${bgScale})`,
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        overflow: "hidden",
      }}
    >
      {/* Decorative elements */}
      <div
        style={{
          position: "absolute",
          top: "-20%",
          right: "-10%",
          width: "40%",
          height: "40%",
          borderRadius: "50%",
          background: "rgba(255,255,255,0.05)",
          filter: "blur(60px)",
        }}
      />
      <div
        style={{
          position: "absolute",
          bottom: "-15%",
          left: "-10%",
          width: "35%",
          height: "35%",
          borderRadius: "50%",
          background: "rgba(255,255,255,0.03)",
          filter: "blur(40px)",
        }}
      />

      {/* Content */}
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          alignItems: scene.style.textAlign === "left" ? "flex-start" : scene.style.textAlign === "right" ? "flex-end" : "center",
          justifyContent: "center",
          padding: "80px",
          maxWidth: "85%",
          textAlign: scene.style.textAlign,
          ...combinedStyles,
        }}
      >
        {/* Icon */}
        {scene.icon && (
          <div
            style={{
              fontSize: scene.style.fontSize * 1.2,
              marginBottom: "20px",
              filter: "drop-shadow(0 4px 8px rgba(0,0,0,0.3))",
            }}
          >
            {scene.icon}
          </div>
        )}

        {/* Title (small label above main text) */}
        {scene.title && scene.title !== scene.text && (
          <div
            style={{
              color: scene.style.textColor,
              fontSize: Math.max(scene.style.fontSize * 0.35, 18),
              fontFamily: scene.style.fontFamily,
              fontWeight: 600,
              letterSpacing: "3px",
              textTransform: "uppercase",
              marginBottom: "16px",
              opacity: 0.7,
            }}
          >
            {scene.title}
          </div>
        )}

        {/* Main text */}
        <div
          style={{
            color: scene.style.textColor,
            fontSize: scene.style.fontSize,
            fontFamily: scene.style.fontFamily,
            fontWeight: 700,
            lineHeight: 1.2,
            textShadow: "0 2px 20px rgba(0,0,0,0.3)",
            letterSpacing: "-0.5px",
          }}
        >
          {getDisplayText(scene.text)}
          {scene.animation.entrance === "typewriter" && frame < entranceDuration * 1.5 && (
            <span
              style={{
                opacity: Math.sin(frame * 0.3) > 0 ? 1 : 0,
                marginLeft: "2px",
              }}
            >
              |
            </span>
          )}
        </div>

        {/* Subtitle */}
        {scene.subtitle && (
          <div
            style={{
              color: scene.style.textColor,
              fontSize: Math.max(scene.style.fontSize * 0.45, 20),
              fontFamily: scene.style.fontFamily,
              fontWeight: 400,
              marginTop: "20px",
              opacity: 0.8,
              lineHeight: 1.5,
            }}
          >
            {getDisplayText(scene.subtitle)}
          </div>
        )}
      </div>
    </AbsoluteFill>
  );
};
