import React from 'react'
import { ReactDom } from 'react-dom';
/**
 * 视频基础组件类
 * props：
 *   src: 视频源地址
 *   lastTime: xx, 上次播放时间
 *   skipBegin: 忽略片头，true/false 
 *   onmeta: 加载资源，可获取如视频长度等信息 父级方法实现
 *   onloaded: 加载完视频，可播放方法 父级方法实现
 *   onloading: 加载中视频 父级方法实现
 *   onplay: 播放视频 父级方法实现
 *   onpause: 暂停播放 父级方法实现
 *   ontime: 
 * 外部可用：
 *   duration
 *   seek
 *   play
 *   pause
 * 
 * 
 * 问题：
 *  1. 华为 P7；小米 自带浏览器，不支持 倍速
 *  2. 视频 跳跃时，可能刷新视频，导致currentTime重新开始
 *  3. 外观不够美化，进度条 不能拖动
 *  4. 图片放大 这个插件也需要集成化
 *  5. 
 */
class VideoPhone extends React.Component {
  static SKIP_SECS = 7; // 片头7s
  /**
   * 构造函数
   */
  constructor(props) {
    /* 继承属性 */
    super(props);
    /* 缓存视频 视频列表 */ 
    this.playList = [];
    /* 视频列表中，播放第几个 */
    this.videoIndex = 0;
    // console.log('diaoyong', this.playList);
    /* 当前所在播放时间 */
    this.time = 0;
    this.stepTimer = null; //time计时器
    // this.lastSeekTime = 0; // 记录上一次 seek时，存储的时间值
  }
  /**
   * 组件渲染前
   */
  componentWillMount() {
  }
  /**
   * 组件渲染后
   */
  componentDidMount() {
    this.refs.video_obj.setAttribute('x5-video-arientation', 'portrait');
    this.refs.video_obj.setAttribute('x-webkit-airplay', 'true');
    this.refs.video_obj.setAttribute('webkit-playsinline', '');
    this.refs.video_obj.setAttribute('playsinline', 'true');
    this.refs.video_obj.setAttribute('x5-video-player-typ', 'h5');
    /* 跟audio组件唯一不同点是 video对象是组件渲染完成后添加 加载Video对象并加载视频 */
    this.getVideoObject()
  }
  componentWillReceiveProps(nextProps) {
    // console.log(12222);
    // if (nextProps.src !== this.props.src) {
    //     // 暂停当前sound
    //     let sound = this.getVideoObject();
    //     if (sound && sound.playing()) {
    //         sound.pause();
    //     }
    //     // 检查是否已存在
    //     let existIndex = findIndex(this.playList, {src: nextProps.src});
    //     if (existIndex < 0) {
    //         existIndex = this.playList.length;
    //         this.playList.push({src: nextProps.src, howl: null, time: 0});
    //     }
    //     this.audioPlay(existIndex);
    // }
  }
  componentWillUnmount() {
    this.getVideoObject().pause();
  }
  shouldComponentUpdate(nextProps, nextState) {
      return false;
  }

  // 第一播放，跳过片头，同时考虑lastTime
  skipBeginAndPlay() {
    let sound = this.getVideoObject();
    if (sound && sound.state() === 'loaded') {
      let lastTime = this.props.lastTime || 0;
      if (this.props.skipBegin) { lastTime = Math.max(lastTime, Video.SKIP_SECS); }
      if (lastTime) {
        if (lastTime > sound.duration() - 10) { lastTime = 0; } // 最后10s不执行跳转lastTime
        let cur = sound.seek();
        if (cur < lastTime) {
            sound.seek(lastTime);
        }
      }
      sound.play();
    }
  }
  // 无参数时，播放当前index视频到对应位置。
  // index 要播放的序号
  audioPlay (index) {
    this.videoIndex = index;
    this.time = 0;

    this.skipBeginAndPlay();
  }
  step() {
      clearTimeout(this.stepTimer);

      let sound = this.getVideoObject();
      if (!sound) {return;}
      let seek = Math.round(sound.seek() || 0);
      let playing = sound.playing();
      if (seek !== this.time) {
          this.time = seek;
          this.props.ontime(seek);
      }
      if (playing) {
          this.stepTimer = setTimeout(this.step, 300);
      }
  }
  stepPause() {
      clearTimeout(this.stepTimer);
      this.props.onpause();
  }

  /**
   * 搜寻点击进度条某个位置 跳播方式
   * @param {number} s 传入当前需要改变的时间 
   */
  seek(s) {
    /**
     * 设置时，需要判断是否在seekable的范围内，不在，等待缓冲 
     * 如果在了，就可以设置 -- 华为手机 就是不行，设置 可能会断，重新加载视频
     */
    let _video = this.getVideoObject(), i = 0;
    // if (!/android/gi.test(navigator.userAgent)) {
    if ('fastSeek' in _video) {
      _video.fastSeek(s); // 改变audio.currentTime的值
      return ;
    }
    this.pause();
    _video.currentTime = s;
    this.play();
    // } else {
    //   for (i=0; i<_video.seekable.length; i++) {
    //     if (_video.seekable.start(i) <= s && s >= _video.seekable.end(i)) {
    //       break;
    //     }
    //   }
    //   if (i < _video.seekable.length) {
    //     _video.currentTime = s;
    //   } else {
    //     _video.buffered.end(_video.buffered.length - 1);
    //   }
    // }

  }

  /**
   * 返回视频长度
   */
  getDuration() {
    return this.getVideoObject().duration || 0;
  }
  /**
   * 开始播放
   */
  play() {
    this.getVideoObject().play();
  }
  /**
   * 播放暂停
   */
  pause() {
    this.getVideoObject().pause();
  }
  /**
   * 播放速率改变
   * @param {float} n 速率值，每次加0.5 
   */
  rate(n) {
    this.getVideoObject().defaultPlaybackRate = n
    this.getVideoObject().playbackRate = n
  }
  /**
   * render渲染
   */
  render () {
    let videoEl = document.createElement("video");

    // 是否支持 MP4
    let isSupportMP4 = videoEl.canPlayType('video/mp4') !== '';
    // 是否支持 HLS 的 m3u8
    let isSupportHLSm3u8 = /like Mac OS X/gi.test(navigator.userAgent);// 判别是否为手机
    // 移动端 支持 m3u8 - 
    // 安卓只支持 application/vnd.apple.mpegurl，而ios对于application/x-mpegURL，application/vnd.apple.mpegURL均支持
    let isSupportm3u8 = videoEl.canPlayType('application/vnd.apple.mpegURL') !== '';

    // alert(isSupportMP4+'1')
    // alert(isSupportHLSm3u8+'2')
    // alert(isSupportm3u8+'3')
    return (<video ref="video_obj" poster={this.props.poster} width="100%" height="100%" videoWidth="" videoHeight="" 
        preload="auto" x5-video-arientation="portrait"
        x-webkit-airplay="true" 
        webkit-playsinline playsinline="true"
        x5-video-player-typ="h5">
        {
          isSupportHLSm3u8 ? 
          <source type="video/mp4" src="https://img.zai-art.com/video1/a264203d6f683194f8bfe7d698beee36.mp4" />
          : isSupportm3u8 ? 
            <source src={this.props.src} />
            : <source type="video/mp4" src="https://img.zai-art.com/video1/a264203d6f683194f8bfe7d698beee36.mp4" />
        }
      </video>)
  }
      // 
  /**
   * 获取 Video对象
   * 内部创建一个 视频对象
   */
  getVideoObject() {
    /* 在缓存视频列表里，获取对应要播放的视频对象 */
    let playItem = this.playList[this.videoIndex];
    /* 如果视频列表里没有 */
    if (!playItem) {
      this.playList[this.videoIndex] = {src: this.props.src, obj: null, time: 0};
      playItem = this.playList[this.videoIndex];
    }
    let _mediaVideo = playItem.obj;
    /* 如果缓存中没有视频对象 */
    if (!_mediaVideo) {
      /* 创建一个Video对象 */
      _mediaVideo = this.refs.video_obj;
      _mediaVideo.src = this.props.src;
      _mediaVideo.load();
      _mediaVideo.loadAll = false; // 可能存在缓存，如果从缓存中获取，那么歌曲就全部加载完成了，就不再需要监听progress事件，虽然它还会继续加载

      /* 开始请求 顺序 1 */
      _mediaVideo.addEventListener('loadstart', () => {

      }, false);
      /* 正在请求 顺序 2, 这个比较特殊，有缓存时，它还会请求 */
      _mediaVideo.addEventListener('progress', () => {
        /* 父级事件，告诉父级视频在加载中 */
        !_mediaVideo.loadAll && this.props.onloading();
        // console.log('loading', !_mediaVideo.loadAll);
      }, false);
      /* 资源长度改 顺序 3 */
      _mediaVideo.addEventListener('durationchange', () => {
        /* 父级事件，告诉父级一些资源信息 华为原生浏览器上，播放前loadedmetadata事件监听，获取不到duration信息 */
        this.props.onmeta();
      }, false);
      /* 可以播放，但中途可能因为加载而暂 顺序 4 */
      _mediaVideo.addEventListener('canplay', () => {
        /* 歌曲可播放，就代表加载完 */
        _mediaVideo.loadAll = true;
        /* 父级事件，告诉父级视频加载完成 */
        this.props.onloaded();
      }, false);
      /* 可以播放，歌曲全部加载完毕 顺序 5 */
      _mediaVideo.addEventListener('canplaythrough', () => {
        /* 父级事件，告诉父级视频加载完成 */
        this.props.onloaded();
      }, false);

      /* play()和autoplay 开始播放时，触发 但并未真正开始播放 */
      _mediaVideo.addEventListener('play', () => {
        /* 父级事件，告诉父级视频正在播放 */
        this.props.onplay();
        /* 父级事件，告诉父级视频在加载中 */
        this.props.onloading();
      }, false);
      /* playing 开始播放时，触发，真正开始播放 */
      _mediaVideo.addEventListener('playing', () => {
        /**
         * 0	HAVE_NOTHING	没有关于视频/视频是否就绪的信息
         * 1	HAVE_METADATA	关于视频/视频就绪的元数据
         * 2	HAVE_CURRENT_DATA	关于当前播放位置的数据是可用的，但没有足够的数据来播放下一帧/毫秒
         * 3	HAVE_FUTURE_DATA	当前及至少下一帧的数据是可用的
         * 4	HAVE_ENOUGH_DATA	可用数据足以开始播放 
         */
        if (_mediaVideo.readyState >= 2) {
          /* 父级事件，告诉父级视频加载完成 */
          this.props.onloaded();
        }
      }, false);
      /* pause() 暂停播放时，触发 */
      _mediaVideo.addEventListener('pause', () => {
        /* 父级事件，告诉父级视频暂停 */
        this.props.onpause();
      }, false);
      /* 获取一些预设信息，事件监听 */
      _mediaVideo.addEventListener('loadedmetadata', () => {
        /* 父级事件，告诉父级一些资源信息 */
        this.props.onmeta();
      }, false);
      // waiting error abort
      /* 播放时间改变时，实时改变进度条 */
      _mediaVideo.addEventListener('timeupdate', () => {
        /* 父级事件，告诉父级当前播放位置 */
        this.props.ontime(_mediaVideo.currentTime);
        // console.log('play');
      }, false);
      
      

      
      /* 设置playbackRate，触发事件ratechange，播放速率改变 */
      _mediaVideo.addEventListener('ratechange', () => {
        // alert(this.getVideoObject().playbackRate)
      }, false);
      /* 设置currentTime，触发事件seeking，寻找中 */
      _mediaVideo.addEventListener('seeking', () => {
        /* 父级事件，告诉父级视频在加载中 */
        this.props.onloading();
      }, false);
      /* 设置currentTime，触发事件seeked，寻找完成 */
      _mediaVideo.addEventListener('seeked', () => {
        /* 父级事件，告诉父级视频加载完成 */
        this.props.onloaded();
      }, false);
      playItem.obj = _mediaVideo;
    }
    return _mediaVideo;
  }
}

module.exports = VideoPhone;
