import React from "react";
import {
  AbsoluteFill,
  Audio,
  interpolate,
  Sequence,
  spring,
  staticFile,
  useCurrentFrame,
  useVideoConfig,
} from "remotion";
import {audioFileFor, script, Sentence} from "./data/script";
import {
  GAP_FRAMES,
  durationForSentence,
  hasAudioForSentence,
} from "./data/timing";

const Title: React.FC<Readonly<{progress: number}>> = ({progress}) => {
  const opacity = interpolate(progress, [0, 1], [0, 1]);
  const translateY = interpolate(progress, [0, 1], [-30, 0]);

  return (
    <div
      style={{
        fontFamily:
          '"IPAexGothic", "IPAPGothic", "M PLUS Rounded 1c", "Hiragino Maru Gothic ProN", sans-serif',
        fontSize: 54,
        fontWeight: 700,
        color: "#1f2a44",
        letterSpacing: 1,
        textAlign: "center",
        marginTop: 40,
        opacity,
        transform: `translateY(${translateY}px)`,
        textShadow: "0 6px 18px rgba(31, 42, 68, 0.2)",
      }}
    >
      ネコミミはなぜかわいい？
    </div>
  );
};

const Subtitle: React.FC<Readonly<{text: string; progress: number}>> = ({
  text,
  progress,
}) => {
  const opacity = interpolate(progress, [0, 1], [0, 1]);
  const translateY = interpolate(progress, [0, 1], [16, 0]);

  return (
    <div
      style={{
        fontFamily:
          '"IPAexGothic", "IPAPGothic", "M PLUS Rounded 1c", "Hiragino Maru Gothic ProN", sans-serif',
        fontSize: 36,
        fontWeight: 700,
        color: "#1a1a1a",
        lineHeight: 1.4,
        padding: "18px 28px",
        backgroundColor: "rgba(255, 255, 255, 0.85)",
        borderRadius: 18,
        border: "2px solid rgba(31, 42, 68, 0.15)",
        boxShadow: "0 10px 30px rgba(31, 42, 68, 0.15)",
        opacity,
        transform: `translateY(${translateY}px)`,
      }}
    >
      {text}
    </div>
  );
};

const Zundamon: React.FC<Readonly<{bounce: number}>> = ({bounce}) => {
  return (
    <div
      style={{
        width: 320,
        height: 320,
        borderRadius: "50%",
        background:
          "radial-gradient(circle at 30% 30%, #c9f6a5, #79d36f 70%)",
        border: "6px solid rgba(31, 42, 68, 0.1)",
        boxShadow: "0 18px 40px rgba(31, 42, 68, 0.2)",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        position: "relative",
        transform: `translateY(${bounce}px)`,
      }}
    >
      <div
        style={{
          position: "absolute",
          top: -60,
          left: 40,
          width: 90,
          height: 90,
          background: "#79d36f",
          borderRadius: "10% 60% 20% 60%",
          transform: "rotate(-18deg)",
          border: "6px solid rgba(31, 42, 68, 0.1)",
        }}
      />
      <div
        style={{
          position: "absolute",
          top: -60,
          right: 40,
          width: 90,
          height: 90,
          background: "#79d36f",
          borderRadius: "60% 10% 60% 20%",
          transform: "rotate(18deg)",
          border: "6px solid rgba(31, 42, 68, 0.1)",
        }}
      />
      <div
        style={{
          display: "flex",
          gap: 36,
        }}
      >
        <div
          style={{
            width: 36,
            height: 46,
            borderRadius: "50%",
            background: "#1f2a44",
          }}
        />
        <div
          style={{
            width: 36,
            height: 46,
            borderRadius: "50%",
            background: "#1f2a44",
          }}
        />
      </div>
      <div
        style={{
          position: "absolute",
          bottom: 68,
          width: 90,
          height: 38,
          borderRadius: "0 0 80px 80px",
          borderBottom: "8px solid #1f2a44",
        }}
      />
    </div>
  );
};

const SentenceSegment: React.FC<Readonly<{sentence: Sentence}>> = ({sentence}) => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();

  const subtitleProgress = spring({
    frame,
    fps,
    config: {damping: 20, mass: 0.7},
  });

  return (
    <>
      <div
        style={{
          position: "absolute",
          bottom: 40,
          left: 0,
          right: 0,
          display: "flex",
          justifyContent: "center",
        }}
      >
        <Subtitle text={sentence.text} progress={subtitleProgress} />
      </div>
      {hasAudioForSentence(sentence) ? (
        <Audio src={staticFile(audioFileFor(sentence.id))} />
      ) : null}
    </>
  );
};

export const YukkuriComposition: React.FC = () => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();

  const titleProgress = spring({
    frame,
    fps,
    config: {damping: 18, mass: 0.6},
  });

  const bounce = interpolate(
    Math.sin((frame / fps) * Math.PI * 2),
    [-1, 1],
    [-10, 10]
  );

  let cursor = 0;
  const sequences = script.map((sentence, index) => {
    const durationInFrames = durationForSentence(sentence, fps);
    const from = cursor;
    cursor += durationInFrames;
    if (index < script.length - 1) {
      cursor += GAP_FRAMES;
    }
    return (
      <Sequence key={sentence.id} from={from} durationInFrames={durationInFrames}>
        <SentenceSegment sentence={sentence} />
      </Sequence>
    );
  });

  return (
    <AbsoluteFill
      style={{
        background:
          "radial-gradient(circle at top, #ffe8c7 0%, #ffd3b4 45%, #ffb6b6 100%)",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
      }}
    >
      <div
        style={{
          position: "absolute",
          inset: 0,
          backgroundImage:
            "radial-gradient(circle at 20% 20%, rgba(255,255,255,0.6) 0, rgba(255,255,255,0) 40%), radial-gradient(circle at 80% 30%, rgba(255,255,255,0.5) 0, rgba(255,255,255,0) 45%), radial-gradient(circle at 30% 80%, rgba(255,255,255,0.4) 0, rgba(255,255,255,0) 50%)",
          opacity: 0.8,
        }}
      />
      <Title progress={titleProgress} />
      <div
        style={{
          flex: 1,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: "100%",
          paddingBottom: 40,
        }}
      >
        <Zundamon bounce={bounce} />
      </div>
      {sequences}
    </AbsoluteFill>
  );
};
