/**
 * 视频类章节
 * props:
 *      username
 *      courseId
 *      chapter 当前章节
 *      ppts
 *      prevChapterId 上一节、下一节对应的章节ID
 *      nextChapterId
 *      curProgress
 *
 *      handlePlayTime 播放时间变化
 *      handleOver 标记已完成
 */
import React, {Component} from 'react'
import { Link } from 'react-router';
import debounce from 'lodash/debounce'
import Video from '../../components/Video.jsx';
import Ppt from '../../components/Ppt.jsx';

let isSkipBegin = false;
if (process.env.BROWSER) {
    isSkipBegin = /skip=1/.test(document.cookie); // 浏览器下根据cookie判断是否跳过片头
}

const PLAY_SPACE_WIDTH = 15;
const PLAY_SPACE_HEIGHT = 10;

const VIDEO_DEFAULT_WIDTH = 550;
const VIDEO_DEFAULT_HEIGHT = 360;

class ChapterVideo extends Component {
    constructor (props) {
        super(props)
        this.state = {
            pptIndex: 0,
            pptBoxOnly: false, // 仅展示ppt框
            pptBoxShow: false, // 展示ppt框
            skipBegin: isSkipBegin, // 跳过片头
            calculatedSize: false // 是否以计算过播放位置的尺寸
        }
        this.videoWidth = VIDEO_DEFAULT_WIDTH;
        this.videoHeight = VIDEO_DEFAULT_HEIGHT;
        this.lastTime = null
    }

    componentDidMount () {
        let size = this.getCalculateSize();
        if (size.video.w) {
            this.videoWidth = size.video.w;
            this.videoHeight= size.video.h;
        }
        // 延迟计算尺寸，因flash初始化需要时间
        setTimeout(this.jdugeSize, 300);

        // 窗口resize，重置大小
        const $ = require('jquery');
        $(window).on('resize.chaptervideo', debounce(this.jdugeSize.bind(this), 200));
    }
    componentWillReceiveProps (nextProps) {
        // 章节变化时，重置位置，并在之后计算大小
        if (nextProps.chapter.id !== this.props.chapter.id) {
            this.videoWidth = VIDEO_DEFAULT_WIDTH;
            this.videoHeight = VIDEO_DEFAULT_HEIGHT;
            this.lastTime = null;
            this._setState({calculatedSize: false})
            setTimeout(this.jdugeSize, 300)
        }
    }
    componentWillUnmount () {
        const $ = require('jquery');
        $(window).off('resize.chaptervideo');
    }

    // 根据时间设置ppt位置
    setPptIndexByTime = time => {
        const ppts = this.props.ppts || []
        const len = ppts.length
        let i = 0;
        for(; i < len; i++) {
            if (time < ppts[i].ppt_point) {
                break;
            }
        }
        if (this.state.pptIndex !== i - 1) {
            this._setState({ pptIndex: i - 1 });
        }
    }
    // 设置视频播放时间点
    setVideoTime = time => {
        if (this.refs.video) {
            this.refs.video.setTimeTo(time);
        }
    };

    // 播放时间变更
    onVideoTimeChange = (e, data) => {
        let time = parseFloat(data.time)
        // 因视频播放完成后也会不断触发playing，因此比对上次时间
        if (this.lastTime === time) { return }
        this.lastTime = time

        // 判断ppt位置
        this.setPptIndexByTime(time)

        this.props.handlePlayTime(time)
    }
    // toggle PPT播放框
    togglePptBox = e => {
        e.preventDefault();
        let isShow = !this.state.pptBoxShow;
        this._setState({
            pptBoxShow: isShow,
            pptBoxOnly: false
        });
        setTimeout(this.jdugeSize, 0)
    };
    // 仅显示ppt播放框
    togglePptBoxOnly = e => {
        e.preventDefault();
        this._setState({ pptBoxOnly: !this.state.pptBoxOnly });
        setTimeout(this.jdugeSize, 0)
    };
    // 跳过片头
    toggleSkipBegin = e => {
        e.preventDefault();
        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();
        if (skip && this.refs.video) {
            this.refs.video.skipBegin();
        }
        this._setState({ skipBegin: skip });
    };
    // 标记完成状态
    handleOver = e => { // 标记完成toggle
        e.preventDefault();
        let t = this.refs.video.getTime();
        this.props.handleOver(t);
    };
    /**
     * 判断并设置尺寸位置
     */
    jdugeSize = () => {
        let box = this.refs.box;
        let size = this.getCalculateSize();
        let uh = 0, uw = 0;

        if (this.state.pptBoxOnly) { // 仅ppt
            uw = size.ppt.w;
            uh = size.ppt.h;
            if (this.refs.ppt) {
                this.refs.ppt.setSize(uw, uh);
            }
        } else if (this.state.pptBoxShow) { // 同时显示video、ppt
            if (this.refs.ppt) {
                this.refs.ppt.setSize(size.ppt.w, size.ppt.h);
            }
            if (this.refs.video) {
                this.refs.video.setSize(size.video.w, size.video.h);
            }
            uw = size.ppt.w + size.video.w;
            uh = size.video.h;
        } else { // 只显示video
            uw = size.video.w;
            uh = size.video.h;
            if (this.refs.video) {
                this.refs.video.setSize(uw, uh);
            }
        }

        this._setState({calculatedSize: true});
        box.style.paddingLeft = '' + ((size.space.w - uw) / 2 + PLAY_SPACE_WIDTH) + 'px';
        box.style.paddingTop = '' + ((size.space.h - uh) / 2 + PLAY_SPACE_HEIGHT) + 'px';
    };
    // 获取各个元素计算后的尺寸
    getCalculateSize = () => {
        let container = this.refs.container;
        let w = container.offsetWidth - PLAY_SPACE_WIDTH * 2;
        let h = container.offsetHeight - 53 - PLAY_SPACE_HEIGHT * 2; // 减去底部操作条高度
        let videoRatio = 550 / 363;
        let pptRatio = 336 / 236;
        let r = {
            space: {w: w, h: h}, // 可容纳play的容器总大小
            video: {w: 0, h: 0}, // 视频大小
            ppt: {w: 0, h: 0}, // ppt容器大小
        };

        if (this.state.pptBoxOnly) { // 仅ppt
            r.ppt.w = w < h * pptRatio ? w : h * pptRatio;
            r.ppt.h = h < w / pptRatio ? h : w / pptRatio;
        } else if (this.state.pptBoxShow) { // 同时显示video、ppt
            let halfW = w / 2;
            let vw = halfW < h * videoRatio ? halfW : h * videoRatio;
            let vh = h < halfW / videoRatio ? h : halfW / videoRatio;
            let ph = vh;
            let pw = ph * pptRatio;
            r.video.w = vw; r.video.h = vh;
            r.ppt.w = pw; r.ppt.h = ph;
        } else { // 只显示video
            r.video.w = w < h * videoRatio ? w : h * videoRatio;
            r.video.h = h < w / videoRatio ? h : w / videoRatio;
        }
        return r;
    }

    _setState = obj => {
        this.setState(Object.assign({}, this.state, obj || {}));
    };

    render () {
        const {chapter, semesterId, courseId, username,
            prevChapterId, nextChapterId,
            curProgress,
            ppts, lastTime} = this.props
        const video = chapter.video;
        const chapterId = chapter.id;
        return (
            <div className="play-content-video" ref="container">
                <div className="play-center cl" ref="box">
                    {video ?
                        <div>
                            <div className={`play-video fl ${this.state.pptBoxOnly ? 'play-video-hide' : ''} ${this.state.calculatedSize ? '' : 'play-video-init-center'}`}>
                                <Video
                                    ref="video"
                                    videoId = {video.video_origionalID}
                                    videoSrt = {video.video_subtitle || ''}
                                    username = {username}
                                    width = {this.videoWidth}
                                    height = {this.videoHeight}
                                    handlePlayTime = {this.onVideoTimeChange}
                                    lastTime={lastTime}
                                />
                            </div>
                            <div className={`play-jiangyi fl ${this.state.pptBoxShow ? '' : 'hide'}`}>
                                <Ppt
                                    ref="ppt"
                                    ppts = {ppts}
                                    currentIndex = {this.state.pptIndex}
                                    onVideoSyncTime = {this.setVideoTime}
                                    onPptOnly = {this.togglePptBoxOnly}
                                    onClose = {this.togglePptBox}
                                />
                            </div>
                        </div>
                        :
                        <p>课程视频数据不存在</p>
                    }
                </div>
                <div className="play-footer">
                    <div className="fl">
                        <Link to={`/courses/${semesterId}/${courseId}/chapters/${prevChapterId || chapterId}`} className={`play-state play-state-prev ${prevChapterId?'': 'play-state-prev-disable'}`}>上一节</Link>
                        <Link to={`/courses/${semesterId}/${courseId}/chapters/${nextChapterId || chapterId}`} className={`play-state play-state-next ${nextChapterId?'': 'play-state-next-disable'}`}>下一节</Link>
                    </div>
                    <div className="fr">
                        <em className={`play-state play-state-check${curProgress == 100 ? '-active' : ''}`} onClick={this.handleOver} data-vid={video && video.id || ''} data-progress={curProgress} data-total={video && video.video_length || 1}>{curProgress == 100 ? '已学完' : '标记为已学完'}</em>
                        {ppts.length ?
                            <em className={`play-state play-state-ppt${this.state.pptBoxShow ? '-active' : ''}`} onClick={this.togglePptBox}>同步显示PPT</em>
                            : null
                        }
                        <em className={`play-state play-state-check${this.state.skipBegin ? '-active' : ''}`} onClick={this.toggleSkipBegin}>始终跳过片头</em>
                    </div>
                </div>
            </div>
        );
    }
}

module.exports = ChapterVideo
