import { AnimatePresence, motion } from "framer-motion";
import {
  ComponentProps,
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from "react";
import { VideoMutingBtn } from "./VideoMutingBtn";
import { VideoProgressBar } from "./VideoProgressBar";

export const VideoPlayer = forwardRef<
  HTMLVideoElement,
  {
    src: string;
    showMutingBtn: boolean;
    children?: React.ReactNode;
  } & ComponentProps<"video">
>(
  (
    { src, showMutingBtn, children, loop = true, autoPlay = true, className },
    ref
  ) => {
    const progressbarRef = useRef<HTMLDivElement>(null);
    const videoRef = useRef<HTMLVideoElement>(null);

    useImperativeHandle(ref, () => videoRef.current!);

    const [muted, setMuted] = useState(autoPlay);
    const [playing, setPlaying] = useState(autoPlay);
    const [progress, setProgress] = useState(0);

    function handleProgressbarClick(e: React.MouseEvent) {
      const video = videoRef.current;
      const bar = progressbarRef.current;
      if (!video || !bar) return;
      video.currentTime =
        (video.duration * (e.clientX - bar.getBoundingClientRect().x)) /
        bar.clientWidth;
      setProgress(
        ((video.currentTime ?? 0) / (video.duration ?? 1)) * 100
      );
    }

    function handlePlaybackClick() {
      if (!videoRef.current) return;
      setPlaying(videoRef.current.paused);
      videoRef.current[videoRef.current.paused ? "play" : "pause"]();
    }

    useEffect(() => {
      const video = videoRef.current;
      if (!video) return;
      const timeUpdateHandler = () =>
        setProgress(((video.currentTime ?? 0) / (video.duration ?? 1)) * 100);

      video.addEventListener("timeupdate", timeUpdateHandler);
      return () => video.removeEventListener("timeupdate", timeUpdateHandler);
    }, []);

    return (
      <div className="relative h-full">
        <video
          ref={videoRef}
          src={src}
          autoPlay={autoPlay}
          muted={muted}
          loop={loop}
          playsInline
          className={`lg:rounded-[1.111vw] rounded-2xl w-full h-full object-cover${
            className ? " " + className : ""
          }`}
        />
        {showMutingBtn && (
          <VideoMutingBtn
            handleClick={() => setMuted(!videoRef.current!.muted)}
            muted={muted}
          />
        )}
        <div className="absolute inset-0 rounded-2xl [background:linear-gradient(to_top,rgba(20,22,31,0.6),rgba(20,22,31,0))]" />
        <AnimatePresence>
          {muted && (
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
            >
              {children}
            </motion.div>
          )}
        </AnimatePresence>
        <VideoProgressBar
          muted={muted}
          progress={progress}
          progressbarRef={progressbarRef}
          playing={playing}
          handlePlaybackClick={handlePlaybackClick}
          handleProgressbarClick={handleProgressbarClick}
        />
      </div>
    );
  }
);

VideoPlayer.displayName = "VideoPlayer";
