import React, {
  forwardRef,
  useRef,
  useState,
  useEffect,
  useMemo,
  useImperativeHandle,
} from 'react';
import Controller from './controller';
import { videoparameter } from '@/interface';
import { FlowContext, useVideoFlow } from '@/core/context';
import useMandatoryUpdate from '@/utils/useMandatoryUpdate';
import Broadcast from '@/components/svgIcon';
import { useVideo } from '@/core/useVideo';
// import videoUrl from '@/assets/haiwang.mp4';
import '@/assets/css/reset.scss';
import './index.scss';

const JoLPlayer = function JoLPlayer(
  {
    videoSrc = 'https://gs-files.oss-cn-hongkong.aliyuncs.com/okr/test/file/2021/07/01/haiwang.mp4',
  }: {
    videoSrc?: string;
  },
  ref: React.Ref<unknown> | undefined,
) {
  /**
   * @description 关灯对象
   */
  const lightOffMaskRef = useRef<HTMLDivElement>(null!);
  /**
   * @description 视频对象
   */
  const videoRef = useRef<HTMLVideoElement>(null!);
  /**
   * @description 视频容器对象
   */
  const videoContainerRef = useRef<HTMLElement>(null!);
  /**
   * @description 定时器检测 3 秒后视频是否可用
   */
  const timerToCheckVideoUseful = useRef<NodeJS.Timeout | null>(null);
  /**
   * @description 视频是否可播发的开关
   */
  const [isVideoUseful, setIsVideoUseful] = useState<boolean>(true);
  /**
   * @description 视频缓存的开关
   */
  const [isBufferring, setIsBufferring] = useState<boolean>(false);

  const { videoFlow, dispatch } = useVideoFlow();

  const forceUpdate = useMandatoryUpdate();

  const waitingListener = () => {
    setIsBufferring(true);
  };

  const playingListener = () => {
    setIsBufferring(false);
  };

  useImperativeHandle(ref, () => ({
    video: videoRef.current,
  }));

  const { isPlay, handleChangePlayState, currentTime, duration, isPictureinpicture } = useVideo(
    {
      videoElement: videoRef.current,
      // onPause: (val: any) => {
      //   console.log(val);
      // },
      // onPlay: (val: any) => {
      //   console.log(val);
      // },
    },
    [videoRef.current],
  );

  useEffect(() => {
    /**
     * @description 设置用户给的视频播放器长宽
     */
    const videoContainerElem = videoContainerRef.current;
    const videoElem = videoRef.current;
    // 设置定时器检测 3 秒后视频是否可用
    timerToCheckVideoUseful.current = setTimeout(() => {
      // 当视频未初始化时（即不可用时）
      if (videoElem.networkState === 0) {
        setIsVideoUseful(false);
      } else {
        clearTimeout(timerToCheckVideoUseful.current!);
      }
    }, 3000);
    // 监听是否在缓冲
    videoElem.addEventListener('waiting', waitingListener);
    // 当开始播放时更改waiting状态
    videoElem.addEventListener('playing', playingListener);
    /**
     * @description 强制更新dom层
     */
    forceUpdate();
    return () => {
      timerToCheckVideoUseful.current && clearTimeout(timerToCheckVideoUseful.current);
      videoElem.removeEventListener('waiting', waitingListener);
      videoElem.removeEventListener('playing', playingListener);
    };
  }, [videoRef.current]);

  const returnVideoSource = useMemo(() => {
    return (
      <>
        <source src={videoSrc} type="video/mp4" />
        <source src={videoSrc} type="video/ogg" />
        <source src={videoSrc} type="video/webm" />
      </>
    );
  }, [videoSrc]);

  const contextProps = useMemo(() => {
    return Object.assign(
      {},
      {
        videoRef: videoRef.current,
        videoContainerRef: videoContainerRef.current,
        lightOffMaskRef: lightOffMaskRef.current,
        dispatch,
        videoFlow,
      },
    );
  }, [videoRef.current, videoFlow]);

  return (
    <figure className="JoL-player-container" ref={videoContainerRef}>
      <div className="light-off-mask" ref={lightOffMaskRef}></div>
      <video className="JoL-player" ref={videoRef}>
        {returnVideoSource}
      </video>
      {!isVideoUseful && <p className="video-no-useful-tip">抱歉！视频找不到了 (｡ ́︿ ̀｡)</p>}
      {isBufferring && (
        <Broadcast iconClass="loading" fill="#ff0000" className="player-loading" fontSize="55px" />
      )}
      <FlowContext.Provider value={contextProps}>
        <Controller />
      </FlowContext.Provider>
    </figure>
  );
};

const JoLPlayerComponent = forwardRef<HTMLVideoElement, any>(JoLPlayer);
export default JoLPlayerComponent;
