import { defineComponent, onMounted, onUnmounted, reactive, toRefs } from 'vue';
import { ref } from 'vue';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css';
import styles from './index.module.less';
import iconplay from '@views/attend-class/image/icon-pause.png';
import iconpause from '@views/attend-class/image/icon-play.png';
import iconReplay from '@views/attend-class/image/icon-replay.png';
import iconPreviewDownload from '@views/attend-class/image/icon-preivew-download2.png';
import iconFullscreen from '@views/attend-class/image/icon-fullscreen.png';
import iconFullscreenExit from '@views/attend-class/image/icon-fullscreen-exit.png';
import iconSpeed from '@views/attend-class/image/icon-speed.png';
import { NSlider, useMessage } from 'naive-ui';
import { saveAs } from 'file-saver';
import { exitFullscreen } from '/src/utils';

export default defineComponent({
  name: 'video-play',
  props: {
    src: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    poster: {
      type: String,
      default: ''
    },
    isEmtry: {
      type: Boolean,
      default: false
    },
    isDownload: {
      type: Boolean,
      default: false
    },
    fullscreen: {
      type: Boolean,
      default: false
    }
  },
  emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset'],
  setup(props, { emit, expose }) {
    const message = useMessage();
    const videoId =
      'vFullscreen' + Date.now() + Math.floor(Math.random() * 100);
    const { src, poster, isEmtry } = toRefs(props);
    const videoFroms = reactive({
      isFullScreen: false, // 是否全屏
      paused: true,
      currentTimeNum: 0,
      currentTime: '00:00',
      durationNum: 0,
      duration: '00:00',
      showBar: true,
      timer: null as any,
      speedControl: false,
      speedStyle: {
        left: '1px'
      },
      defaultSpeed: 1 // 默认速度
    });
    const videoRef = ref();
    const videoItem = ref();
    const videoID = 'video' + Date.now() + Math.floor(Math.random() * 100);

    // 对时间进行格式化
    const timeFormat = (num: number) => {
      if (num > 0) {
        const m = Math.floor(num / 60);
        const s = num % 60;
        return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
      } else {
        return '00:00';
      }
    };

    //
    const toggleHideControl = (isShow = false) => {
      videoFroms.showBar = isShow;
      videoFroms.speedControl = false;
    };

    const onReplay = () => {
      videoFroms.speedControl = false;
      if (!videoItem.value) return;
      videoItem.value.currentTime(0);
    };

    // 切换音频播放
    const onToggleVideo = (e?: MouseEvent) => {
      videoFroms.speedControl = false;
      e?.stopPropagation();
      if (videoFroms.paused) {
        videoItem.value.play();
        videoFroms.paused = false;
      } else {
        videoItem.value.pause();
        videoFroms.paused = true;
      }
      emit('togglePlay', videoFroms.paused);
    };

    // 下载资源
    const onDownload = () => {
      if (!props.src) {
        message.error('下载失败');
        return;
      }
      const fileUrl = props.src;
      // 发起Fetch请求
      fetch(fileUrl)
        .then(response => response.blob())
        .then(blob => {
          saveAs(blob, props.title || new Date().getTime() + '');
        })
        .catch(() => {
          message.error('下载失败');
        });
    };

    /** 延迟收起模态框 */
    const setModelOpen = (status = true) => {
      clearTimeout(videoFroms.timer);
      toggleHideControl(status);
      videoFroms.timer = setTimeout(() => {
        toggleHideControl(false);
      }, 3000);
    };

    const __init = () => {
      if (videoItem.value) {
        videoItem.value.poster(poster.value); // 封面
        videoItem.value.src(isEmtry.value ? '' : src.value); // url 播放地址

        // 初步加载时
        videoItem.value.one('loadedmetadata', () => {
          console.log(' Loading metadata');

          // 获取时长
          videoFroms.duration = timeFormat(
            Math.round(videoItem.value.duration())
          );
          videoFroms.durationNum = videoItem.value.duration();

          emit('loadedmetadata', videoItem.value);
          onToggleVideo();
        });

        // 视频播放时加载
        videoItem.value.on('timeupdate', () => {
          videoFroms.currentTime = timeFormat(
            Math.round(videoItem.value?.currentTime() || 0)
          );
          videoFroms.currentTimeNum = videoItem.value.currentTime();
        });

        // 视频播放结束
        videoItem.value.on('ended', () => {
          videoFroms.paused = true;
          emit('ended');
        });

        videoItem.value.on('play', () => {
          setModelOpen();
        });

        videoItem.value.on('pause', () => {
          clearTimeout(videoFroms.timer);
          videoFroms.showBar = true;
        });
      }
    };

    /** 全屏 */
    const isElementFullscreen = (element: any) => {
      const dom: any = document;
      return (
        element ===
        (dom.fullscreenElement ||
          dom.webkitFullscreenElement ||
          dom.mozFullScreenElement ||
          dom.msFullscreenElement)
      );
    };
    const onFullScreen = () => {
      const el: any = document.querySelector('#' + videoId);
      //   //进入全屏
      if (el) {
        if (isElementFullscreen(el)) {
          exitFullscreen();
        } else {
          (el.requestFullscreen && el.requestFullscreen()) ||
            (el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
            (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
            (el.msRequestFullscreen && el.msRequestFullscreen());
        }
        // videoFroms.isFullScreen = isElementFullscreen(el);
      }
    };

    const onFullScreenChange = () => {
      if (document.fullscreenElement) {
        videoFroms.isFullScreen = true;
      } else {
        videoFroms.isFullScreen = false;
      }
    };

    onMounted(() => {
      videoItem.value = TCPlayer(videoID, {
        appID: '',
        controls: false,
        autoPlay: true
      }); // player-container-id 为播放器容器 ID，必须与 html 中一致
      __init();
      window.addEventListener('fullscreenchange', onFullScreenChange);
    });
    onUnmounted(() => {
      window.removeEventListener('fullscreenchange', onFullScreenChange);
      if (videoItem.value) {
        videoItem.value.pause();
        videoItem.value.dispose();
        videoItem.value = null;
      }
    });

    expose({
      // changePlayBtn,
      toggleHideControl
    });
    return () => (
      <div
        class={[styles.videoWrap, 'videoWrapModal']}
        id={videoId}
        onClick={() => setModelOpen(!videoFroms.showBar)}
        onTouchstart={() => setModelOpen(!videoFroms.showBar)}>
        <div class={[styles.videoContent]}>
          <video
            style={{ width: '100%', height: '100%' }}
            src={isEmtry.value ? '' : src.value}
            poster={poster.value}
            ref={videoRef}
            id={videoID}
            preload="auto"
            playsinline
            webkit-playsinline></video>

          <div
            class={[
              styles.controls,
              videoFroms.showBar ? '' : styles.sectionAnimate
            ]}
            onClick={(e: MouseEvent) => {
              e.stopPropagation();
              emit('reset');
              setModelOpen();
            }}
            onTouchstart={(e: any) => {
              e.stopPropagation();
              emit('reset');
              setModelOpen();
            }}>
            <div class={styles.actions}>
              <div class={styles.actionWrap}>
                <button class={styles.actionBtn} onClick={onToggleVideo}>
                  {videoFroms.paused ? (
                    <img class={styles.playIcon} src={iconplay} />
                  ) : (
                    <img class={styles.playIcon} src={iconpause} />
                  )}
                </button>

                <button class={styles.iconReplay} onClick={onReplay}>
                  <img src={iconReplay} />
                </button>

                <div
                  class={styles.actionBtnSpeed}
                  onClick={(e: any) => {
                    e.stopPropagation();
                    videoFroms.speedControl = !videoFroms.speedControl;
                    if (videoFroms.speedControl) {
                      clearTimeout(videoFroms.timer);
                      videoFroms.showBar = true;
                    } else {
                      setModelOpen(true);
                    }
                  }}>
                  <img src={iconSpeed} />

                  <div
                    style={{
                      display: videoFroms.speedControl ? 'block' : 'none'
                    }}>
                    <div
                      class={styles.sliderPopup}
                      onClick={(e: Event) => {
                        e.stopPropagation();
                      }}>
                      <i
                        class={styles.iconAdd}
                        onClick={() => {
                          if (videoFroms.defaultSpeed >= 1.5) {
                            return;
                          }

                          if (videoItem.value) {
                            videoFroms.defaultSpeed =
                              (videoFroms.defaultSpeed * 10 + 1) / 10;
                            videoItem.value.playbackRate(
                              videoFroms.defaultSpeed
                            );
                          }
                        }}></i>
                      <NSlider
                        value={videoFroms.defaultSpeed}
                        step={0.1}
                        max={1.5}
                        min={0.5}
                        vertical
                        tooltip={false}
                        onUpdate:value={(val: number) => {
                          videoFroms.defaultSpeed = val;
                          if (videoItem.value) {
                            videoItem.value.playbackRate(
                              videoFroms.defaultSpeed
                            );
                          }
                        }}>
                        {{
                          thumb: () => (
                            <div class={styles.sliderPoint}>
                              {videoFroms.defaultSpeed}
                              <span>x</span>
                            </div>
                          )
                        }}
                      </NSlider>
                      <i
                        class={[styles.iconCut]}
                        onClick={() => {
                          if (videoFroms.defaultSpeed <= 0.5) {
                            return;
                          }
                          if (videoItem.value) {
                            videoFroms.defaultSpeed =
                              (videoFroms.defaultSpeed * 10 - 1) / 10;
                            videoItem.value.playbackRate(
                              videoFroms.defaultSpeed
                            );
                          }
                        }}></i>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <div class={styles.slider}>
              <NSlider
                value={videoFroms.currentTimeNum}
                step={0.01}
                max={videoFroms.durationNum}
                tooltip={false}
                onUpdate:value={(val: number) => {
                  videoFroms.speedControl = false;
                  videoItem.value.currentTime(val);
                  videoFroms.currentTimeNum = val;
                  videoFroms.currentTime = timeFormat(Math.round(val || 0));
                }}
              />
            </div>

            <div class={styles.actions}>
              <div class={styles.time}>
                <div
                  class="plyr__time plyr__time--current"
                  aria-label="Current time">
                  {videoFroms.currentTime}
                </div>
                <span class={styles.line}>/</span>
                <div
                  class="plyr__time plyr__time--duration"
                  aria-label="Duration">
                  {videoFroms.duration}
                </div>
              </div>
              <div class={styles.actionWrap}>
                {props.isDownload && (
                  <button class={styles.iconDownload} onClick={onDownload}>
                    <img src={iconPreviewDownload} />
                  </button>
                )}
                {props.fullscreen && (
                  <button class={styles.iconDownload} onClick={onFullScreen}>
                    <img
                      src={
                        videoFroms.isFullScreen
                          ? iconFullscreenExit
                          : iconFullscreen
                      }
                    />
                  </button>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
});
