"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Pause, Play, RotateCcw, SkipBack, SkipForward } from "lucide-react";
import type {
  AnimationSettings,
  Caption,
  CaptionLayout,
  CaptionStyle,
  VideoMeta,
} from "@/types";
import { Button } from "@/components/ui/button";
import { CaptionWord } from "@/components/caption-word";
import { cn } from "@/lib/utils";

interface VideoPreviewProps {
  videoUrl: string;
  audioUrl?: string;
  captions: Caption[];
  style: CaptionStyle;
  layout: CaptionLayout;
  animation: AnimationSettings;
  videoMeta: VideoMeta;
}

export function VideoPreview({
  videoUrl,
  audioUrl,
  captions,
  style,
  layout,
  animation,
  videoMeta,
}: VideoPreviewProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const [currentMs, setCurrentMs] = useState(0);
  const [playing, setPlaying] = useState(false);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const onTimeUpdate = () => setCurrentMs(video.currentTime * 1000);
    video.addEventListener("timeupdate", onTimeUpdate);
    return () => video.removeEventListener("timeupdate", onTimeUpdate);
  }, []);

  useEffect(() => {
    const video = videoRef.current;
    if (!video || !audioUrl) return;
    video.muted = true;
  }, [audioUrl]);

  const togglePlay = useCallback(() => {
    const video = videoRef.current;
    if (!video) return;
    if (video.paused) {
      void video.play();
      setPlaying(true);
    } else {
      video.pause();
      setPlaying(false);
    }
  }, []);

  const seekBy = (delta: number) => {
    const video = videoRef.current;
    if (!video) return;
    video.currentTime = Math.max(0, Math.min(video.duration, video.currentTime + delta));
  };

  const restart = () => {
    const video = videoRef.current;
    if (!video) return;
    video.currentTime = 0;
    setCurrentMs(0);
  };

  // ponytail: strict window — the +200ms grace stacked the outgoing phrase under the new one
  const visibleCaptions = captions.filter(
    (c) => c.startMs <= currentMs && currentMs < c.endMs,
  );

  const positionClass =
    layout.position === "top"
      ? "top-[15%]"
      : layout.position === "center"
        ? "top-1/2 -translate-y-1/2"
        : "bottom-[15%]";

  return (
    <div className="space-y-4">
      {/* ponytail: container-query context so captions scale with the preview instead
          of using raw export px, which looked ~4x too big in a 292px-wide frame */}
      <div
        className="relative overflow-hidden rounded-xl bg-black shadow-lg"
        style={{ containerType: "inline-size" }}
      >
        <video
          ref={videoRef}
          src={videoUrl}
          className="aspect-[9/16] max-h-[520px] w-full object-contain"
          playsInline
          muted={!!audioUrl}
          onEnded={() => setPlaying(false)}
        />
        {audioUrl && (
          <audio ref={(el) => {
            if (el && videoRef.current) {
              videoRef.current.onplay = () => void el.play();
              videoRef.current.onpause = () => el.pause();
              videoRef.current.onseeked = () => { el.currentTime = videoRef.current!.currentTime; };
            }
          }} src={audioUrl} />
        )}
        <div
          className={cn(
            "pointer-events-none absolute inset-x-0 flex justify-center px-4",
            positionClass,
          )}
          style={{ transform: layout.yOffset ? `translateY(${layout.yOffset}px)` : undefined }}
        >
          <div
            className="flex flex-wrap justify-center gap-2 rounded-[1.7cqw] px-[2.6cqw] py-[1.7cqw]"
            style={{ backgroundColor: style.backdrop }}
          >
            {visibleCaptions.map((caption) => (
              <CaptionWord
                key={caption.id}
                caption={caption}
                currentMs={currentMs}
                style={style}
                animation={animation}
              />
            ))}
          </div>
        </div>
      </div>

      <div className="flex items-center justify-center gap-2">
        <Button variant="outline" size="icon" onClick={() => seekBy(-5)}>
          <SkipBack className="h-4 w-4" />
        </Button>
        <Button variant="outline" size="icon" onClick={restart}>
          <RotateCcw className="h-4 w-4" />
        </Button>
        <Button size="icon" onClick={togglePlay}>
          {playing ? <Pause className="h-4 w-4" /> : <Play className="h-4 w-4" />}
        </Button>
        <Button variant="outline" size="icon" onClick={() => seekBy(5)}>
          <SkipForward className="h-4 w-4" />
        </Button>
      </div>
      <p className="text-center text-xs text-zinc-500">
        {videoMeta.width}×{videoMeta.height} • {videoMeta.fps} fps • {Math.round(videoMeta.duration)}s
      </p>
    </div>
  );
}
