import React, { createRef, useCallback, useEffect, useRef } from "react";
import { useStore } from "../store";

const MediaPlayer = () => {
  const setPercentageElapsed = useStore((state) => state.setPercentageElapsed);

  // use it as a guard to avoid multiple set states inside updateTime
  const lastSetPercentageRef = useRef<undefined | number>(undefined);
  const language = useStore((state) => state.language);

  const requestRef = useRef();
  const videoRef = createRef<HTMLVideoElement>();
  const trackRef = createRef<HTMLTrackElement>();
  const subtitleRef = createRef<HTMLParagraphElement>();

  useEffect(() => {
    const handleCueChange = (e: any) => {
      const { track } = e.target;
      const { activeCues } = track;
      const text = [...activeCues].map(
        (cue) => cue.getCueAsHTML().textContent
      )[0];
      if (subtitleRef.current && videoRef.current) {
        if (!text || videoRef.current.currentTime === 0)
          subtitleRef.current.textContent = text;
        else subtitleRef.current.textContent = text;
      }
    };

    if (trackRef.current) {
      trackRef.current.addEventListener("cuechange", handleCueChange);
    }
  }, [subtitleRef, trackRef, videoRef]);

  const updateTime = useCallback(() => {
    (requestRef.current as any) = requestAnimationFrame(updateTime);
    if (videoRef.current) {
      const timeElapsed = videoRef.current.currentTime;
      const duration = videoRef.current.duration;
      const percentageElapsed = Math.floor((timeElapsed / duration) * 100);

      if (
        percentageElapsed % 5 === 0 &&
        lastSetPercentageRef.current !== percentageElapsed
      ) {
        setPercentageElapsed(percentageElapsed);
        lastSetPercentageRef.current = percentageElapsed;

        if (subtitleRef.current) {
          if (percentageElapsed === 0) {
            subtitleRef.current.style.visibility = "visible";
          } else if (percentageElapsed === 100) {
            subtitleRef.current.style.visibility = "hidden";
          }
        }
      }
    }
  }, [setPercentageElapsed, videoRef, subtitleRef]);

  useEffect(() => {
    (requestRef.current as any) = requestAnimationFrame(updateTime);
    const curr = requestRef.current;
    return () => {
      cancelAnimationFrame(curr as any);
      setPercentageElapsed(0);
    };
  }, [setPercentageElapsed, updateTime]);

  return (
    <>
      <video id="media" ref={videoRef} disablePictureInPicture>
        <track id={"track"} ref={trackRef} kind="metadata" default />
      </video>
      <div id={"subtitle-container"}>
        <p
          ref={subtitleRef}
          id={"subtitle"}
          style={language === "ko" ? { fontFamily: "sans-serif", wordBreak: "keep-all" } : {}}
        />
      </div>
    </>
  );
};

export default MediaPlayer;