import React, { useEffect, useRef, useContext, useState, useImperativeHandle } from 'react';
import { LoadingOutlined } from '@ant-design/icons';
import { message, ConfigProvider, Progress, Slider, Spin } from 'antd';
import classNames from 'classnames';
import moment from 'moment';
import Empty from '@wisdom-components/empty';
import empty_icon from '../../assets/缺省页.png';
import backward_icon from './assets/backward.svg';
import forward_icon from './assets/forward.svg';
import expend_icon from './assets/expend.svg';
import mute_icon from './assets/mute.svg';
import play_icon from './assets/play.svg';
import stop_icon from './assets/stop.svg';
import volume_icon from './assets/volume.svg';
import reload_icon from './assets/reload.svg';
import play_big_icon from './assets/play_big.svg';
import TimeSlider from '../TimeSlider';
import { hiswsUrl } from '../../apis';
import './index.less';

const HKh5player = (props, ref) => {
  const IS_MOVE_DEVICE = document.body.clientWidth < 992; // 是否移动设备
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('hk-h5-player-view');
  const { VideoInfo = {}, JessibucaObj, ProgressBar, EmptyIcon = '' } = props;
  const videoID = VideoInfo?.id || `VIDEO_PLAY_BACK${Date.now().toString(36)}`;
  const [showId, setShowId] = useState(VideoInfo?.id || ''); //视频ID
  const [peridos, setPeridos] = useState([]); //可播放视频时间段
  const [hoursRuler, setHoursRuler] = useState(VideoInfo.hoursRuler || 24);
  const [playTimestamp, setPlayTimestamp] = useState(
    VideoInfo?.playTime ? moment(VideoInfo?.playTime).valueOf() : null,
  ); //当前正在播放时间段
  const [minTimestamp, setMinTimestamp] = useState(null); //时间轴最小时间
  const [maxTimestamp, setMaxTimestamp] = useState(null); //时间轴最大时间
  const [loading, setLoading] = useState(false); // 初始化加载状态
  const [sping, setSping] = useState(false); // 视频加载状态
  const [percent, setPercent] = useState(0);
  const [playStatus, setPlayStatus] = useState(false);
  const [playSpeed, setPlaySpeed] = useState(1);
  const [mutedStatus, setMutedStatus] = useState(false);
  const [soundSize, setSoundSize] = useState(50);
  const [fullStatus, setFullStatus] = useState(false);
  const [streamEnd, setStreamEnd] = useState(false);
  const videoUrl = useRef(null);
  const timeRef = useRef(null);
  const player = useRef(null);

  useEffect(() => {
    setShowId(props?.VideoInfo?.id || '');
    setHoursRuler(props?.VideoInfo.hoursRuler || 24);
    const playTimes = props?.VideoInfo?.playTime
      ? moment(props?.VideoInfo?.playTime).valueOf()
      : null;
    setPlayTimestamp(playTimes);
    changeReplayCfg?.(playTimes);
    // 设置播放容器的宽高并监听窗口大小变化
    window.addEventListener('resize', resizeVideo);
    return () => {
      window.removeEventListener('resize', resizeVideo);
      player.current?.removeAllListeners?.();
      player.current?.JS_Destroy?.();
      player.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.VideoInfo]);

  useEffect(() => {
    if (peridos.length && player.current && playTimestamp) {
      const endTime = moment(peridos?.[0].endTime).format('YYYY-MM-DD HH:mm:ss');
      const beginTime = moment(playTimestamp).format('YYYY-MM-DD HH:mm:ss');
      playbackToSeek({ beginTime: beginTime, endTime: endTime });
      player.current?.JS_Resize?.();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [playTimestamp]);

  useEffect(() => {
    let current = percent;
    if (loading)
      timeRef.current = setInterval(() => {
        current = current + 1;
        setPercent(current > 99 ? 99 : current);
      }, 20);

    return () => {
      if (timeRef.current) {
        clearInterval(timeRef.current);
        timeRef.current = null;
        setPercent(0);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [loading]);

  // 设置播放容器的宽高并监听窗口大小变化
  const resizeVideo = () => {
    player.current?.JS_Resize?.();
  };

  // 更改播放配置
  const changeReplayCfg = (playTimes) => {
    const {
      beginTime = moment().format('YYYY-MM-DD 00:00:00'),
      endTime = moment().format('YYYY-MM-DD 23:59:59'),
      id = '',
    } = props?.VideoInfo || {};
    if (!id) return setShowId(null);
    const hoursPerRuler = calculateHours(beginTime, endTime) || 24;
    const stTimes = moment(beginTime).format('YYYY-MM-DD HH:mm:ss');
    const edTimes =
      moment(new Date()).valueOf() >= moment(endTime).valueOf()
        ? moment(endTime).format('YYYY-MM-DD HH:mm:ss')
        : moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
    const params = {
      id: id,
      startTime: stTimes,
      endTime: edTimes,
      'site-code':
        window?.globalConfig?.userInfo?.LocalSite || window?.globalConfig?.userInfo?.site || '',
    };
    setHoursRuler(hoursPerRuler);
    setMinTimestamp(moment(stTimes).valueOf());
    setMaxTimestamp(moment(edTimes).valueOf());
    setPlayTimestamp(playTimes ? playTimes : moment(stTimes).valueOf());
    setPeridos([
      {
        beginTime: moment(beginTime).valueOf(),
        endTime: moment(endTime).valueOf(),
        style: { background: '#637DEC' },
      },
    ]);
    setLoading(true);
    hiswsUrl(params)
      .then((res) => {
        setLoading(false);
        if (res.code === 200) {
          const data = res?.data || '';
          const url = data.split('?')[0].split('/').pop() || '';
          if (!url) return setShowId(null);
          videoUrl.current = url;
          getVideoReplayInfo({
            beginTime: playTimestamp
              ? moment(playTimestamp).format('YYYY-MM-DD HH:mm:ss')
              : stTimes,
            endTime: edTimes,
          });
        } else {
          setShowId(null);
          message.warn(res.msg);
        }
      })
      .catch((err) => {
        setLoading(false);
        setShowId(null);
      });
  };

  // 获取计算小时数
  const calculateHours = (time1, time2) => {
    const date1 = new Date(time1);
    const date2 = new Date(time2);
    const diff = Math.abs(date1.getTime() - date2.getTime());
    return Math.ceil(diff / (1000 * 60 * 60));
  };

  // 获取视频配置信息
  const getVideoReplayInfo = (times) => {
    createPlayer();
    playbackStart({ beginTime: times.beginTime, endTime: times.endTime });
    player.current?.JS_Resize?.();
  };

  // 创建视频播放
  const createPlayer = () => {
    player.current = new window.JSPlugin({
      szId: videoID,
      szBasePath: JessibucaObj?.decoder || '/h5player',
      iMaxSplit: 1,
      iCurrentSplit: 1,
      openDebug: false,
      oStyle: {
        borderSelect: IS_MOVE_DEVICE ? '#000' : '#000',
      },
    });

    // 事件回调绑定
    player.current?.JS_SetWindowControlCallback?.({
      windowEventSelect: (iWndIndex) => {
        //插件选中窗口回调
      },
      pluginErrorHandler: (iWndIndex, iErrorCode, oError) => {
        //插件错误回调
        playbackReload();
      },
      windowEventOver: (iWndIndex) => {
        //鼠标移过回调
      },
      windowEventOut: (iWndIndex) => {
        //鼠标移出回调
      },
      windowEventUp: (iWndIndex) => {
        //鼠标mouseup事件回调
      },
      windowFullCcreenChange: (bFull) => {
        //全屏切换回调
      },
      firstFrameDisplay: (iWndIndex, iWidth, iHeight) => {
        //首帧显示回调
      },
      performanceLack: () => {
        //性能不足回调
      },
      StreamEnd: () => {
        setStreamEnd(true);
        setPlayStatus(false);
        setPlayTimestamp(null);
      },
    });

    player.current?.JS_SetConnectTimeOut?.(0, 10)?.then(
      () => {},
      (err) => {},
    );
  };

  // 视频开始播放
  const playbackStart = (times) => {
    const index = 0;
    const playURL = `ws://${window?.location?.host || ''}/openUrl/${videoUrl.current}`;
    const beginTime = times.beginTime.replaceAll(' ', 'T') + 'Z';
    const endTime = times.endTime.replaceAll(' ', 'T') + 'Z';
    setSping(true);
    setPlaySpeed(1);
    setMutedStatus(false);
    setSoundSize(50);
    player.current?.JS_Play?.(playURL, { playURL, mode: 1 }, index, beginTime, endTime)?.then(
      () => {
        setSping(false);
        setPlayStatus(true);
      },
      (e) => {
        setSping(false);
        // console.error(e);
      },
    ) || setSping(false);
  };

  // 视频定位播放
  const playbackToSeek = (times) => {
    const beginTime = times.beginTime.replaceAll(' ', 'T') + 'Z';
    const endTime = times.endTime.replaceAll(' ', 'T') + 'Z';
    player.current?.JS_Seek?.(0, beginTime, endTime)?.then(
      () => {},
      (e) => {
        // console.error(e);
      },
    );
  };

  // 视频刷新播放
  const playbackReload = () => {
    setPlayStatus(false);
    const {
      beginTime = moment().format('YYYY-MM-DD 00:00:00'),
      endTime = moment().format('YYYY-MM-DD 23:59:59'),
    } = props?.VideoInfo || {};
    const bgTimes = moment(beginTime).format('YYYY-MM-DD HH:mm:ss');
    const edTimes = moment(endTime).format('YYYY-MM-DD HH:mm:ss');
    player.current?.JS_GetOSDTime?.()?.then(
      (time) => {
        playbackStart({
          beginTime: moment(time).format('YYYY-MM-DD HH:mm:ss'),
          endTime: edTimes,
        });
      },
      (e) => {
        playbackStart({
          beginTime: bgTimes,
          endTime: edTimes,
        });
      },
    );
  };

  // 视频播放状态
  const handVideoPlay = () => {
    if (!player.current) return false;
    if (playStatus) {
      // 暂停播放
      player.current?.JS_Pause?.()?.then(
        () => {
          setPlayStatus(false);
        },
        (e) => {
          // console.error(e);
        },
      );
    } else {
      // 恢复播放
      player.current?.JS_Resume?.().then(
        () => {
          setPlayStatus(true);
        },
        (e) => {
          // console.error(e);
        },
      );
    }
  };

  // 视频慢放
  const handVideoSpeedSlow = () => {
    if (!player.current) return false;
    player.current?.JS_Slow?.()?.then(
      (rate) => {
        if (rate > 0) {
          setPlaySpeed(rate);
        } else {
          setPlaySpeed(1 / Math.abs(rate));
        }
      },
      (e) => {
        // console.error(e);
      },
    );
  };

  // 视频快放
  const handVideoSpeedFast = () => {
    if (!player.current) return false;
    player.current?.JS_Fast?.()?.then(
      (rate) => {
        if (rate > 0) {
          setPlaySpeed(rate);
        } else {
          setPlaySpeed(1 / Math.abs(rate));
        }
      },
      (e) => {
        // console.error(e);
      },
    );
  };

  // 视频声音控制
  const handVideoSound = () => {
    if (!player.current) return false;
    if (mutedStatus) {
      player.current?.JS_CloseSound?.()?.then(
        () => {
          setMutedStatus(false);
          setSoundSize(50);
        },
        (e) => {
          // console.error(e)
        },
      );
    } else {
      player.current?.JS_OpenSound?.()?.then(
        () => {
          setMutedStatus(true);
          setSoundSize(50);
        },
        (e) => {
          // console.error(e)
        },
      );
    }
  };

  // 视频声音改变
  const changeVideoSlider = (value) => {
    if (!player.current || !mutedStatus) return false;
    player.current?.JS_SetVolume?.(0, value)?.then(
      () => {
        setSoundSize(value);
      },
      (e) => {
        // console.error(e)
      },
    );
  };

  // 视频全屏
  const handVideoFull = () => {
    if (!player.current) return false;
    // 全屏
    player.current?.JS_FullScreenSingle?.(0)?.then(
      () => {},
      (e) => {
        // console.error(e);
      },
    );
  };

  // 视频刷新
  const handVideoReload = () => {
    playbackReload();
  };

  // 视频重新播放
  const handReloadVideo = () => {
    setStreamEnd(false);
    const {
      beginTime = moment().format('YYYY-MM-DD 00:00:00'),
      endTime = moment().format('YYYY-MM-DD 23:59:59'),
    } = props?.VideoInfo || {};
    const bgTimes = moment(beginTime).format('YYYY-MM-DD HH:mm:ss');
    const edTimes = moment(endTime).format('YYYY-MM-DD HH:mm:ss');
    playbackStart({
      beginTime: bgTimes,
      endTime: edTimes,
    });
  };

  // 视频容器渲染
  const videoBoxRender = () => {
    return (
      <>
        <div className={classNames(`${prefixCls}-content`)}>
          <div
            id={videoID}
            className={classNames(`${prefixCls}-video`)}
            style={{ width: '100%', height: '600px' }}
          />
          <ul className={classNames(`${prefixCls}-control`)}>
            <li className={classNames(`${prefixCls}-control-play`)}>
              <img src={playStatus ? stop_icon : play_icon} onClick={handVideoPlay} />
            </li>
            <li className={classNames(`${prefixCls}-control-speed`)}>
              <div
                className={classNames(
                  `${prefixCls}-control-speed-btn`,
                  playSpeed === 0.25 ? `${prefixCls}-control-speed-none` : '',
                )}
                onClick={handVideoSpeedSlow}
              >
                <img src={backward_icon} />
              </div>
              <span className={classNames(`${prefixCls}-control-speed-value`)}>{playSpeed}x</span>
              <div
                className={classNames(
                  `${prefixCls}-control-speed-btn`,
                  playSpeed === 4 ? `${prefixCls}-control-speed-none` : '',
                )}
                onClick={handVideoSpeedFast}
              >
                <img src={forward_icon} />
              </div>
            </li>
            <li className={classNames(`${prefixCls}-control-sound`)}>
              <img src={mutedStatus ? volume_icon : mute_icon} onClick={handVideoSound} />
              <div className={classNames(`${prefixCls}-control-sound-slider`)}>
                <Slider
                  className={classNames(`${prefixCls}-control-sound-slider-list`)}
                  vertical
                  onChange={changeVideoSlider}
                  value={soundSize}
                />
              </div>
            </li>
            <li className={classNames(`${prefixCls}-control-full`)} onClick={handVideoFull}>
              <img src={expend_icon} />
            </li>
            <li className={classNames(`${prefixCls}-control-reload`)} onClick={handVideoReload}>
              <img src={reload_icon} />
            </li>
          </ul>
        </div>
        {/* 时间轴 */}
        <div className={classNames(`${prefixCls}-time`)}>
          {peridos.length ? (
            <TimeSlider
              key={JSON.stringify(props?.VideoInfo || {})}
              minTimestamp={minTimestamp}
              maxTimestamp={maxTimestamp}
              hoursPerRuler={hoursRuler || 24}
              playTimestamp={playTimestamp ? playTimestamp : peridos?.[0]?.beginTime}
              playTimestampChange={(time, recordInfo, playOffset) => {
                if (recordInfo && playOffset) {
                  setPlayTimestamp(time);
                } else {
                  message.warn('当前时间节点超出回放时间区间！');
                }
              }}
              timecell={peridos}
            />
          ) : null}
        </div>
        {streamEnd && (
          <div className={classNames(`${prefixCls}-stream`)}>
            <img src={play_big_icon} onClick={handReloadVideo} />
            <span>视频回放播放结束，可点击播放重新查看回放</span>
          </div>
        )}
        {sping && (
          <div className={classNames(`${prefixCls}-spin`)}>
            <Spin
              className={classNames(`${prefixCls}-spin-box`)}
              tip="视频回放正在加载中..."
              indicator={
                <LoadingOutlined
                  style={{
                    fontSize: 48,
                  }}
                />
              }
            />
            ;
          </div>
        )}
      </>
    );
  };

  // 加载容器渲染
  const loadBoxRender = () => {
    return (
      <>
        <div className={classNames(`${prefixCls}-load`)}>
          <Progress
            className={classNames(`${prefixCls}-progress`)}
            strokeColor={ProgressBar?.strokeColor || ''}
            format={(percent) => {
              return (
                <span style={{ color: ProgressBar?.textColor || 'unset' }}>{percent + '%'}</span>
              );
            }}
            strokeWidth={14}
            percent={percent}
          />
          <span style={{ color: ProgressBar?.textColor || 'unset' }}>
            视频回放信息获取中，请稍后...
          </span>
        </div>
      </>
    );
  };

  // 缺省页容器渲染
  const emptyBoxRender = () => {
    return (
      <div className={classNames(`${prefixCls}-empty`)}>
        <Empty
          image={EmptyIcon || empty_icon}
          theme={'dark'}
          description={'咦~暂时没有查询到视频回放信息呢~'}
        />
      </div>
    );
  };

  return (
    <div className={classNames(`${prefixCls}`)}>
      {loading ? loadBoxRender() : showId ? videoBoxRender() : emptyBoxRender()}
    </div>
  );
};

export default HKh5player;
