import React from 'react'
import { Link } from 'react-router'
import sortedIndex from 'lodash/sortedIndex'
import {toTimeString} from '../../libs/utils'
import VideoPhone from './VideoPhone.jsx'
import ProgressCircle from '../../components/ProgressCircle.jsx'
import Loading from '../../components/Loading.jsx'
import {chapterType} from '../../libs/const'

let pagePlayMap = {};
const RATES = [1.0,1.2,1.5,2.0,2.5,3.0]

let isSkipBegin = false;
if (process.env.BROWSER) {
    require('css/videoPlay.css');
    // require('howler/dist/howler.min.js');
    // require('previewImage');
    isSkipBegin = /skip=1/.test(document.cookie); // 浏览器下根据cookie判断是否跳过片头
}

class VideoPhonePanel extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            pptIndex: 0,

            loading: true, // 是否加载中
            playing: false, // 是否播放中
            time: 0, // 当前播放时间
            duration: 0, // 总的播放时间
            rateIndex: 0, //是否加倍
            skipBegin: isSkipBegin, // 跳过片头

            showChapter: false,  // 显示章节弹出层
        };
        this.pptTimes = this.props.ppts.map(ppt => ppt.ppt_point);
        this.pagePlayMap = pagePlayMap; // 播放期间记录本次页面进度 {[time, progress]}

        this._setState = this._setState.bind(this);

        this.getAudio = this.getAudio.bind(this);
        this.getProgress = this.getProgress.bind(this);

        this.onAudioMeta = this.onAudioMeta.bind(this);
        this.onAudioLoad = this.onAudioLoad.bind(this);
        this.onAudioLoading = this.onAudioLoading.bind(this);
        this.onAudioPlay = this.onAudioPlay.bind(this);
        this.onAudioPause = this.onAudioPause.bind(this);
        this.onAudioCurrentTime = this.onAudioCurrentTime.bind(this);

        this.toggleChapter = this.toggleChapter.bind(this);
        this.toggleSet = this.toggleSet.bind(this);

        this.handlePlay = this.handlePlay.bind(this);
        this.handleForward = this.handleForward.bind(this);
        this.handleBackward = this.handleBackward.bind(this);
        this.handleTouchBar = this.handleTouchBar.bind(this);

        this.handleOver = this.handleOver.bind(this);
        this.handleSkip = this.handleSkip.bind(this);
        this.handleRate = this.handleRate.bind(this);
        this.handleClickList = this.handleClickList.bind(this);
        this.handlePptView = this.handlePptView.bind(this);
    }
    componentDidMount() {
    }
    componentWillReceiveProps(nextProps) {
        // 切换index，重置audio相关state
        //if (nextProps.index !== this.props.index) {
        //    this._setState({time: 0})
        //}
        // 更新pptTimes
        if (nextProps.ppts !== this.props.ppts) {
            this.pptTimes = nextProps.ppts.map(ppt => ppt.ppt_point);
        }
    }
    componentWillUnmount() {
        this.unmounted = true; // 标记unmount状态，防止音频停止事件触发setState
        let preview = document.getElementById('__previewImage-container');
        if (preview) {
            preview.style.display = 'none';
        }
    }
    shouldComponentUpdate(nextProps, nextState) {
        return this.state !== nextState || this.props !== nextProps;
    }
    _setState(obj) {
        this.setState((prevState, props) => Object.assign({}, prevState, obj || {}))
    }

    getAudio() {
        return this.refs.video;
    }
    // 获取进度，综合接口返回上次播放进度和本页播放进度记录
    getProgress(id) {
        let p = 0;
        let pageProg = (this.pagePlayMap[id] || [])[1] || 0;
        let dataProg = ((this.props.chapterData.progressMap || {})[id] || {}).chapter_progress || 0;
        p = Math.max(pageProg, dataProg);
        return p;
    }

    /**
     * 章节层显示与否
     */
    toggleChapter() {
        this._setState({ showChapter: !this.state.showChapter });
    }
    toggleSet() {
        this._setState({ showSet: !this.state.showSet });
    }
    // 点击章节列表外面隐藏
    handleClickList(e) {
        if (e.target === e.currentTarget) {
            this._setState({showChapter: false});
        }
    }


    
    // seek
    handleTouchBar(e) {
      if (this.state.loading) return;
      e = e.nativeEvent;
      let x = e.pageX || e.clientX;
      const $ = require('jquery');
      let bar = $('#video-bar');
      let toX = x - bar.offset().left;
      if (toX >= 0) {
        let audio = this.getAudio();
        let time = toX / bar.width() * this.state.duration;
        audio.seek(time);
        /* 跳播时，实时改变进度条 */
        this.onAudioCurrentTime(time);
      }
    }
    // 前15s
    handleBackward() {
      let audio = this.getAudio();
      audio.seek(Math.max(0, this.state.time - 15));
    }
    // 后15s
    handleForward() {
      let audio = this.getAudio();
      audio.seek(Math.min(this.state.duration - (+this.state.playing), this.state.time + 15));
    }

    // 标记完成
    handleOver() {
        this.props.handleOver(this.state.time);
    }
    // 通过previewImage预览图片
    handlePptView(e) {
        if (typeof previewImage !== 'object') return;
        let list = this.props.ppts.map(ppt => ppt.ppt_url);
        if(!list.length) {
            list.push(this.props.course.curriculum && this.props.course.curriculum.curriculum_picture || '')
        }
        previewImage.start({
            urls: list,
            current: list[this.state.pptIndex]
        });
    }

    formatTime(seconds) {
        return toTimeString(Math.round(seconds), seconds >= 3600 ? 'h:m:s' : 'm:s');
    }
  /**
   * 点击播放 click方法 
   */
  handlePlay() {
    if (this.state.loading) return;
    let audio = this.getAudio();
    if (this.state.playing) {
      audio.pause();
    } else {
      audio.play();
    }
  }
  /**
   * 跳过片头 click方法
   */
  handleSkip() {
    let skip = +(!this.state.skipBegin);
    let d = new Date();
    d.setMonth(d.getMonth() + 1);
    document.cookie = 'skip=' + skip + ';path=/;domain=.ezijing.com;expires=' + d.toGMTString();
    this._setState({ skipBegin: skip });
  }
  /**
   * 控制倍速 click方法
   */
  handleRate() {
    let audio = this.getAudio();
    if (audio) {
      let l = RATES.length;
      let from = this.state.rateIndex;
      let to = (from + 1 + l) % l;

      this._setState({ rateIndex: to});
      audio.rate(RATES[to]);
    }
  }
  // 处理Audio事件, 向下组件传递内容
  /**
   * 获取资源信息
   */
  onAudioMeta() {
    this._setState({duration: this.refs.video.getDuration()});
  }
  /**
   * 音频加载中
   */
  onAudioLoading() {
    this._setState({loading: true});
  }
  /**
   * 音频加载完成，可以播放
   */
  onAudioLoad() {
    this._setState({loading: false});
  }
  /**
   * 音频播放事件
   */
  onAudioPlay() {
    this._setState({playing: true});
  }
  /**
   * 音频停止事件
   */
  onAudioPause() {
    if (this.unmounted) return;
    this._setState({playing: false});
  }
  /**
   * 实时改变当前时间
   * @param {number} time 当前时间 
   */
  onAudioCurrentTime(time) {
    if (this.unmounted) return;
    // 更新当前播放时间
    this._setState({time: time});
    // 更新当前进度
    const cid = this.props.chapterData.leaves[this.props.index];
    this.pagePlayMap[cid] = [time, Math.round(time/this.state.duration * 100)];
    // 检查ppt是否需要更新
    if (this.pptTimes.length) {
      let pptIndex = this.pptTimes.indexOf(time);
      if (pptIndex < 0) {
        pptIndex = sortedIndex(this.pptTimes, time);
        pptIndex = Math.max(0, pptIndex - 1);
      }
      if (this.state.pptIndex !== pptIndex) {
        this._setState({pptIndex});
      }
    }

    this.props.handleVideoTime(time);
  }

    render() {
        const {pptIndex, time, duration, playing, loading} = this.state;
        const {index, chapterData, ppts, course, video_curm3u8} = this.props;
        const chapter = chapterData.map[chapterData.leaves[index]];
        if (!course || !course.course_id || !chapter) {
            return <div></div>
        }
        const ppt = ppts[pptIndex] || {};
        const isFirst = index === 0, isLast = index === chapterData.leaves.length - 1;
        const timeStr = this.formatTime(time);
        const durationStr = this.formatTime(duration);

        // 上次进度时间
        let lastTime = 0;
        if (this.pagePlayMap[chapter.id]) {
            lastTime = this.pagePlayMap[chapter.id][0] || 0;
        } else {
            lastTime = (chapterData.progressMap[chapter.id] || {}).last_position || 0;
        }

        const HEADER = <header>
                    <h1>{course.course_name || ''}</h1>
                    <Link to={`/courses/${course.course_id}`} className="play-back-phone">&nbsp;</Link>
                </header>
        /* 视频还没加载完成 */
        if(!video_curm3u8.video) {
            return <div><Loading/></div>
        }
        // 是否支持播放音频
        return  <div className="page-video">
                    {HEADER}
                    <p className="text-error" style={{color:'#f00'}}>暂不支持手机端播放视频文件</p>
                </div>

        return (
            <div className="page-video">
                {HEADER}
                <section className="play-wrap rel">
                    <VideoPhone
                        ref="video"
                        src={video_curm3u8.streaming[0].playurl}
                        lastTime={lastTime}
                        skipBegin={this.state.skipBegin}
                        onmeta={this.onAudioMeta}
                        onloading={this.onAudioLoading}
                        onloaded={this.onAudioLoad}
                        onplay={this.onAudioPlay}
                        onpause={this.onAudioPause}
                        ontime={this.onAudioCurrentTime}
                        poster={course.curriculum && course.curriculum.curriculum_picture || ''}
                    />
                    <button type="button" onTouchEnd={this.toggleSet} className={`play-set-btn ${this.state.showSet ? 'disable' : ''}`}></button>
                    <div className={`play-set ${this.state.showSet ? '' : 'hide' }` } >
                        <div>
                            <div className="play-set-time"><em>{timeStr}</em>／{durationStr}</div>
                            <div style={{display: "flex"}}>
                                <button onTouchEnd={this.handleSkip} className={`play-jump ${this.state.skipBegin ? 'disable' : ''}`}><em></em><br/>跳过片头</button>
                                <button onTouchEnd={this.handleBackward} className="play-set-button play-minus"></button>
                                <button onTouchEnd={this.handleForward} className="play-set-button play-add"></button>
                                <button onTouchEnd={this.handleRate} className="play-set-button play-double">{RATES[this.state.rateIndex].toFixed(1)}X<br/>倍速播放</button>
                            </div>
                        </div>
                    </div>
                </section>
                <footer>
                    <div className="play-timer">
                        <div className="video-bar" onClick={this.handleTouchBar} id="video-bar"><span className="video-progress" style={{width: ''+(duration ? time / duration * 100 : 0)+'%'}}></span></div>
                        <div className="show-time">
                            <span className="cur-time">{timeStr}</span>
                            <span className="total-time">{durationStr}</span>
                        </div>
                    </div>

                    <div className="play-ctrls">
                        <div className="ctrl-items play-ctrl-chapter" onTouchEnd={this.toggleChapter}><em></em><br/>章节</div>
                        <div className="ctrl-items btns">
                            <Link to={`/courses/${course.course_id}/chapters/${isFirst ? chapter.id : chapterData.leaves[index - 1]}`} type={`button ${isFirst ? 'disable' : ''}`} className={`button play-prev ${isFirst ? 'disable' : ''}`}>
                            </Link>
                            <button type="button" onClick={this.handlePlay} className={`button play-btn ${loading ? 'play-load' : playing ? 'play-pause' : 'play-play'}`}>{loading ? <Loading/> : ''}</button>
                            <Link to={`/courses/${course.course_id}/chapters/${isLast ? chapter.id : chapterData.leaves[index + 1]}`} type={`button ${isLast ? 'disable' : ''}`} className={`button play-next ${isLast ? 'disable' : ''}`}>
                            </Link>
                        </div>
                        <div className={`ctrl-items play-ctrl-mark ${this.getProgress(chapter.id) === 100 ? 'disable' : ''}`} onTouchEnd={this.handleOver}><em></em><br/>标记为已学完</div>
                    </div>
                    <div className={`play-chapter ${this.state.showChapter ? '' : 'hide' }` } onClick={this.handleClickList}>
                        <div className="play-chapter-inner">
                            {chapterData.tree.map((tree, i) => {
                                let root = chapterData.map[tree[0]];
                                return (
                                    <dl key={i}>
                                        <dt>{root.name}</dt>
                                        {tree[1].map((leaf, j) => {
                                            leaf = chapterData.map[leaf];
                                            return (
                                                <dd key={j} className={index === chapterData.leaves.indexOf(leaf.id) ? 'on' : ''}>
                                                    <div className="cl">
                                                        <ProgressCircle percent={this.getProgress(leaf.id)} className="play-prog" />
                                                        <Link to={`/courses/${course.course_id}/chapters/${leaf.id}`}>{leaf.name}</Link>
                                                        {leaf.type === chapterType.VIDEO ?
                                                            <span className="fr">{this.formatTime(leaf.video && leaf.video.video_length || 0)}</span>
                                                            : null
                                                        }
                                                    </div>
                                                </dd>
                                            );
                                        })}
                                    </dl>
                                );
                            })}
                        </div>
                    </div>
                </footer>
            </div>
        )
    }
}

module.exports = VideoPhonePanel;
