import React, { Component } from 'react';
import { connect } from 'react-redux'
import { Link } from 'react-router';

import { chapterType } from '../../libs/const';
import { getIdt, getRequestTypes, paramify } from '../../libs/utils';
import CoursesAction from '../../actions/CoursesAction';
import OperateAction from '../../actions/OperateAction';
import Loading from '../../components/Loading.jsx';

// 页面组成部分
import SideList from './SideList.jsx'
import SidePpt from './SidePpt.jsx'
import ChapterVideo from './ChapterVideo.jsx'
import ChapterRead from './ChapterRead.jsx'
import ChapterExam from './ChapterExam.jsx'
import ChapterWork from './ChapterWork.jsx'
import CourseWork from './CourseWork.jsx'
import CourseInfo from './CourseInfo.jsx'
import AudioPanel from './AudioPanel.jsx'
import VideoPhonePanel from './VideoPhonePanel.jsx'

if (process.env.BROWSER) {
    require('css/course.css');
    require('css/play.css');
}

const SIDEBAR_CHAPTER = 'sidebar_chapter';
const SIDEBAR_PPT = 'sidebar_ppt';
const IS_PHONE = /Android|iPhone|iPad/i.test(navigator && navigator.userAgent || '');

class Play extends Component {
    // 初始加载数据
    // static fetchData({dispatch, params={}, location={}, apiClient}) {
    //     const courseAction = new CoursesAction({ apiClient });
    //     let arr = [
    //         dispatch( courseAction.loadCourseDetail(params.courseId) ),
    //         dispatch( courseAction.loadChapterProgress(params.courseId) )
    //     ];
    //     return Promise.all(arr);
    // }

    constructor(props) {
        super(props);
        this.state = {
            sidebar: IS_PHONE ? false : SIDEBAR_CHAPTER, // 控制侧边栏显示与否，及显示chapter还是ppt
            pptBoxOnly: false, // 仅展示ppt框
            pptBoxShow: false, // 展示ppt框
            curProgress: 0, // 当前播放章节的进度，仅为更新this.pageProgressMap时，触发页面刷新
        };

        this.pageProgressMap = {}; // 播放期间记录本次页面进度
        // 需上传数据
        this.pushData = {
            timer: null, // 定期发送timer
            currentChapterId: null,
            currentVideoId: null, // 当前播放视频id

            total: 0, // 播放累计总时间
            max: 0, // 最大播放时间点
            arr: [], // 播放数组
            last: 0, // 上次播放时间点，用来与当前第一个点比较是否重复
        };
        this.courseAction = new CoursesAction();
        this.operateAction = new OperateAction();

        this.getChapterMap = this.getChapterMap.bind(this);
        this.getCurrentChapter = this.getCurrentChapter.bind(this);
        this.getProgress = this.getProgress.bind(this);
    }

    componentDidMount() {
        this._chapterMap = null;
        const {params, course}  = this.props;
        // 如果没有指定章节ID，并且又取得了章节数据，跳转到第一节
        if (!params.chapterId &&
                (params.courseId === (course._req && course._req.courseId) && course.data)) {
            let chapters = course.data && course.data.chapters || [];
            let children = chapters[0] && chapters[0].children || [];
            let firstId = children[0] && children[0].id;
            this.props.history.push(`/courses/${params.semesterId}/${params.courseId}/chapters/${firstId}`);
            return;
        }

        this.loadNeededData(this.props);

        // 数据采集
        this.pushData.timer = setInterval(this.sendPlayerProgress.bind(this), 5000);
    }
    componentDidUpdate() {
        //if (this.refs.chapterVideo) {
        //    this.refs.chapterVideo.jdugeSize()
        //}
    }
    componentWillReceiveProps(nextProps) {
        this.loadNeededData(nextProps);
        // 如果章节变化，需要再次获取最新的私密信息，以便保证每次播放都检查权限
        if (this.props.location.pathname !== nextProps.location.pathname) {
            // this.sendPlayerProgress();
        }

        if (this.props.video_progress.isFetching !== nextProps.video_progress.isFetching &&
                nextProps.video_progress.data) {
            let cur = this.getCurrentChapter(nextProps.params.chapterId);
            if (cur) {
                let video_progress = nextProps.video_progress.data;
                Object.assign(this.pushData, {
                    currentVideoId: cur.video.id,
                    total: (video_progress.pt || 0) - 0,
                    max: (video_progress.mpt || 0) - 0,
                    last: (video_progress.cpt || 0) - 0,
                })
            }
        }
    }
    componentWillUnmount() {
        let operateAction = new OperateAction();
        this.props.dispatch(operateAction.cleanData(CoursesAction.LOAD_COURSE_DETAIL));
        this.props.dispatch(operateAction.cleanData(CoursesAction.LOAD_CHAPTER_PROGRESS));

        clearInterval(this.pushData.timer);
        this.sendPlayerProgress();
    }

    // 获取章节map
    getChapterMap() {
        if (!this._chapterMap) {
            let ret = null;
            let info = this.props.course.data || {};
            let list = info.chapters || [];
            list.forEach(chapter => {
                (chapter.children || []).forEach(item => {
                    ret = ret || {};
                    ret[item.id] = item;
                });
            });
            this._chapterMap = ret;
        }
        return this._chapterMap;
    }
    // 获取当前章节
    getCurrentChapter(chapterId) {
        let cur = null;
        let id = chapterId || this.props.params.chapterId;
        let map = this.getChapterMap();
        if (map && id) {
            cur = map[id];
        }
        return cur;
    }
    /**
     * 加载需要的数据：已有数据与props中参数不一致时，加载对应的数据
     */
    loadNeededData = props => {
        const {params, course, ppts, user} = props;
        const courseAction = new CoursesAction();
        // 课程详情
        if (params.courseId != (course._req && course._req.courseId)) {
            props.dispatch( courseAction.loadCourseDetail(params.semesterId, params.courseId) );
            props.dispatch( courseAction.loadChapterProgress(params.semesterId, params.courseId) );
        }
        // 课程章节
        if (params.chapterId !== this.pushData.currentChapterId && course.data) {
            // 只有章节数据存在时，才加载当前视频进度
            let curChapter = this.getCurrentChapter(params.chapterId);
            if (curChapter && curChapter.video) {
                this.pushData.currentChapterId = params.chapterId;
                props.dispatch( courseAction.loadPlayerProgress({
                    device_id: getIdt(),
                    video_id: curChapter.video.id,
                    semester_id: params.semesterId
                    //_idt: getIdt(),
                    //_uid: user.data && user.data.uid || null,
                    //_cid: params.courseId,
                    //_vid: curChapter.video.id,
                }) );
                // 存在章节时，加载ppt
                if (curChapter.video &&
                    curChapter.video.id &&
                    curChapter.video.id != (ppts._req && ppts._req.videoId)) {
                        props.dispatch( courseAction.loadVideoPpts(curChapter.video.id) );
                    }
                /* 读取对应视频 - 手机端 m3u8源 */
                props.dispatch( courseAction.loadVideoPhone({ vid: curChapter.video.id }) )
            }
        }
    };

    // 发送到数据采集
    sendPlayerProgress = () => {
        if (this.pushData.arr.length && this.pushData.currentVideoId) {
            const courseAction = new CoursesAction();
            const len = this.pushData.arr.length;
            this.pushData.total += len - (this.pushData.last === this.pushData.arr[0] ? 1 : 0);
            this.pushData.last = this.pushData.arr[len - 1];
            this.pushData.max = Math.max.apply(null, [this.pushData.max].concat(this.pushData.arr))

            // 更新pageProgressMap
            let chapter = this.getCurrentChapter();
            if (chapter) {
                let v = Math.ceil(this.pushData.max / chapter.video.video_length * 100);
                this.pageProgressMap[chapter.id] = v;
                if (this.state.curProgress != v) {
                    this.setState({curProgress: v});
                }
            }

            let params = {
                d: getIdt(),
                i: getIdt(),
                c: this.props.params.courseId,
                s: this.props.params.semesterId,
                v: this.pushData.currentVideoId,
                //_ts: Math.round(new Date().getTime() / 1000),

                _p: this.pushData.total,
                _m: this.pushData.max > chapter && chapter.video.video_length ? chapter.video.video_length : this.pushData.max,
                _c: this.pushData.last > chapter && chapter.video.video_length ? chapter.video.video_length : this.pushData.last,
            };
            this.props.dispatch( courseAction.playerProgress(params) );

            // 再次推送另一个系统
            delete params._dt_0;
            const imgId = '_tj_pt_gif_';
            let img = document.getElementById(imgId);
            if (!img) {
                img = new Image();
                img.id = imgId;
                img.style.display = 'none';
                document.body.appendChild(img);
            }
            img.src = 'https://tj.ezijing.com/pt.gif?' + paramify(params);
            this.pushData.arr = [];
        }
    };
    // 阅读材料统计进度
    sendReaded = () => {
        let chapter = this.getCurrentChapter();
        if (chapter && chapter.reading) {
            let params = {
                d: getIdt(),
                i: getIdt(),
                c: this.props.params.courseId,
                s: this.props.params.semesterId,
                r: chapter.reading.id
            };
            const courseAction = new CoursesAction();
            this.props.dispatch( courseAction.chapterReaded(params) );

            this.pageProgressMap[chapter.id] = 100;
        }
    };
    chapterSubmited = id => {
        this.pageProgressMap[id] = 100;
    };

    // 点击返回详情时，重新加载课程的private信息，以便更新latest_play字段数据
    onClickToDetail = e => {
        const courseAction = new CoursesAction();
        this.props.dispatch( courseAction.loadCoursePrivate(this.props.params.courseId) );
    };

    changeSidebar = (v) => {
        this.setState({sidebar: v});
        if (v != this.state.sidebar && (v === false || this.state.sidebar === false)) {
            if (this.refs.chapterVideo) {
                setTimeout(() => {
                    this.refs.chapterVideo.jdugeSize()
                }, 0)
            }
        }
    }
    // 侧边点击ppt，根据ppt播放时间点同步video
    // @param index 被点击的ppt序列号
    handleClickSidePpt = index => {
        const ppts = this.props.ppts.data || []
        if (ppts.length > index && this.refs.chapterVideo) {
            const ppt = ppts[index]
            this.refs.chapterVideo.setVideoTime(ppt.ppt_point)
        }
    };
    handlePlayTime = time => { // 视频播放时间变更调用此方法
        // 侧边ppt对应位置
        if (this.refs.sidePpt) {
            this.refs.sidePpt.setIndexByPoint(time)
        }

        // 存储到要上传到大数据的数据集中
        time = Math.round(time);
        if (this.pushData.arr.indexOf(time) < 0) {
            this.pushData.arr.push(time);
        }
    };
    // 标记完成
    // @param time 当前播放到的时间点
    handleOver = time => {
        let cur = this.getCurrentChapter();
        let progress = this.getProgress(cur.id);
        if (cur) {
            this._signOver = progress != 100;
            this.props.dispatch( this.courseAction[progress == 100 ? 'playerUnover': 'playerOver']({
                video_id: cur.video.id,
                chapter_id: cur.id,
                current_progress: Math.round(time/cur.video.video_length * 100)
            }) );
        }
    };
    // 获取进度，综合接口返回上次播放进度和本页播放进度记录
    getProgress(id) {
        const progressData = this.props.chapter_progress.data || {};
        if (id === 'work') { // 大作业
            return Math.max(
                progressData.essay && progressData.essay.progress || 0,
                this.pageProgressMap.essay || 0);
        }

        let p = 0;
        let chapterProgressMap = progressData.chapters || {};
        let pobj = chapterProgressMap[id] || {};
        if (id === this.props.params.chapterId) {
            p = (this._signOver || (pobj.sign && this._signOver === undefined)) ? 100 : pobj.progress || 0;
        } else {
            p = pobj.sign ? 100 : pobj.progress || 0;
        }
        p = Math.max(this.pageProgressMap[id] || 0, p);
        return p;
    }

    render() {
        let {course, ppts, params, user, video_curm3u8, video_progress} = this.props;
        if (course.isFetching) {
            return <div className="play"><Loading /></div>
        } else if (!(course.data && course.data.course_id)) {
            return <div className="play"><p className="no-data">课程不存在</p></div>
        }
        let cpt = (video_progress.data || {}).cpt || 0;
        course = course.data || {};
        let chapters = course.chapters || [];
        ppts = ppts.data || [];

        video_curm3u8 = video_curm3u8.data || {};

        // 构造chapterMap，方便查找；顺便在同一个遍历中创建层级结构
        let chapterMap = this.getChapterMap() || {};  // map
        // 当前章节
        let chapter = params.chapterId && chapterMap[params.chapterId] || {};
        // 当前章节进度
        let curProgress = this.getProgress(params.chapterId);

        this.pushData.currentVideoId = chapter.video && chapter.video.id || null;
        const isVideo = chapter.type === chapterType.VIDEO;
        // 前一节、后一节
        let leafIds = [];
        chapters.forEach(c => {
            (c.children || []).forEach(o => {
                leafIds.push(o.id);
            });
        });
        let prevChapterId = null;
        let nextChapterId = null;
        let curIndex = leafIds.indexOf(params.chapterId);
        prevChapterId = curIndex > 0 ? leafIds[curIndex - 1] : null;
        nextChapterId = curIndex < leafIds.length - 1 ? leafIds[curIndex + 1] : null;

        if (isVideo && !video_progress.data) {
            return <div className="play"><Loading /></div>
        }
        /* 手机端 没用 device接口传的 lastTime值 */
        if (IS_PHONE && !video_curm3u8.video && !video_curm3u8.audio) {
            return <div><Loading/></div>
        }
        /* 手机播放页面单独展示 - 音频播放 */
        if (isVideo && IS_PHONE && video_curm3u8.audio) {
            if (!this.audioChapterData) {
                let map = {}; // {chapterId: chapterObj}
                let tree = []; // [[cid, [cid, cid]]]
                let leaves = [];
                chapters.forEach(c => {
                    map[c.id] = c;
                    tree.push([c.id, []]);
                    c.children.forEach(o => {
                        map[o.id] = o;
                        leaves.push(o.id)
                        tree[tree.length - 1][1].push(o.id);
                    })
                })
                this.audioChapterData = {map, tree, leaves,
                    progressMap: this.props.chapter_progress.data || {}};
            }
            return  <div className="play">
                        <AudioPanel
                            index={curIndex}
                            chapterData={this.audioChapterData}
                            course={course}
                            ppts={ppts}
                            skipBegin={false}
                            handleOver={this.handleOver}
                            handleAudioTime = {this.handlePlayTime}
                            video_curm3u8={video_curm3u8}
                        />
                    </div>
        } else
        /* 有视频时，先播放视频, 并且存在手机端 m3u8时 */
        if (isVideo && IS_PHONE && !chapter.video.video_voice) {
            if (!this.audioChapterData) {
                let map = {}; // {chapterId: chapterObj}
                let tree = []; // [[cid, [cid, cid]]]
                let leaves = [];
                chapters.forEach(c => {
                    map[c.id] = c;
                    tree.push([c.id, []]);
                    c.children.forEach(o => {
                        map[o.id] = o;
                        leaves.push(o.id)
                        tree[tree.length - 1][1].push(o.id);
                    })
                })
                this.audioChapterData = {map, tree, leaves,
                    progressMap: this.props.chapter_progress.data || {}
                };
            }
            return (<div className="play">
                        <VideoPhonePanel
                            index={curIndex}
                            chapterData={this.audioChapterData}
                            course={course}
                            ppts={ppts}
                            video_curm3u8={video_curm3u8}
                            skipBegin={false}
                            handleOver={this.handleOver}
                            handleVideoTime = {this.handlePlayTime}
                        />
                    </div>)
        }
        return (
            <div className={`play ${this.state.sidebar ? '' : 'sidebar-hide'}`}>
                <div className="left-content">
                    <div className="play-top cl" style={this.state.sidebar ? {} : {marginRight: 0}}>
                        <Link className="play-back" to={`/courses/${params.semesterId}/${params.courseId}/cont`} onClick={this.onClickToDetail}>&lt;</Link>
                        <p>{course.course_name}</p>
                        <p>{chapter.chapter_name}</p>
                    </div>
                    <div className="play-content">
                        {params.chapterId === 'work' ?
                            <CourseWork
                                course={course}
                                semesterId={course.semester_id}
                                course_work={this.props.course_work}
                                dispatch={this.props.dispatch}
                                action={this.props.action}
                                handleSubmited={this.chapterSubmited}
                            />
                            : params.chapterId === 'info' ?
                            <CourseInfo
                                courseId={params.courseId}
                                files={course.files}
                            />
                            : chapter.type === chapterType.VIDEO ?
                            <ChapterVideo
                                ref="chapterVideo"
                                courseId={params.courseId}
                                semesterId={course.semester_id}
                                ppts={ppts}
                                chapter={chapter}
                                username={user.data && user.data.username || ''}
                                prevChapterId={prevChapterId}
                                nextChapterId={nextChapterId}
                                curProgress={curProgress}
                                handlePlayTime={this.handlePlayTime}
                                handleOver={this.handleOver}
                                lastTime={cpt}
                            />
                            : chapter.type === chapterType.WORKOREXAM ?
                            (chapter.homework && chapter.homework.work_type === chapterType.WORK_HOME ?
                                <ChapterWork
                                    chapter={chapter}
                                    chapter_work={this.props.chapter_work}
                                    courseId={params.courseId}
                                    semesterId={course.semester_id}
                                    action={this.props.action}
                                    dispatch={this.props.dispatch}
                                    handleSubmited={this.chapterSubmited}
                                />
                                :
                                <ChapterExam
                                    chapter={chapter}
                                    chapter_work={this.props.chapter_work}
                                    courseId={params.courseId}
                                    semesterId={course.semester_id}
                                    action={this.props.action}
                                    dispatch={this.props.dispatch}
                                    handleSubmited={this.chapterSubmited}
                                />
                            )
                            :
                            <ChapterRead
                                chapter={chapter}
                                handleReaded={this.sendReaded}
                            />
                        }
                    </div>
                </div>
                <div className="right-content" style={{ right: this.state.sidebar ? 0 : -388 }}>
                    <p className="right-arrow" onClick={this.handleHideSidebar}><span>&gt;</span></p>
                    <div className="control-panel">
                        <ul className="nav-tabs play-nav cl">
                            <li className={`videoChapter ${this.state.sidebar === SIDEBAR_CHAPTER ? 'current' : ''}`}><a href="#sidebar_chapter" onClick={this.handleShowSidebarChapter}>章节</a></li>
                            {ppts.length ?
                                <li className={`videoJy ${this.state.sidebar === SIDEBAR_PPT ? 'current' : ''}`}><a href="#sidebar_ppt" onClick={this.handleShowSidebarPpt}>讲义</a></li>
                                : null
                            }
                        </ul>
                        <div className="tab-content">
                            {this.state.sidebar === SIDEBAR_CHAPTER ?
                                <SideList
                                    chapters={chapters}
                                    getProgressByChapterId={this.getProgress}
                                    courseId={params.courseId}
                                    semesterId={params.semesterId}
                                    chapterId={params.chapterId}
                                    progress={curProgress}
                                    handleClickItem={IS_PHONE ? this.handleHideSidebar1 : this.reloadPages}
                                />
                                :
                                <SidePpt
                                    ref="sidePpt"
                                    ppts={ppts}
                                    handleClickPpt={this.handleClickSidePpt}
                                />
                            }
                        </div>
                    </div>
                </div>
                {this.state.sidebar ? null :
                    <div className="switch">
                        <a href="#sidebar_chapter" className="switch-chapter" onClick={this.handleShowSidebarChapter}></a>
                        {isVideo && ppts.length ?
                            <a href="#sidebar_ppt" className="switch-handout" onClick={this.handleShowSidebarPpt}></a>
                            : null
                        }
                    </div>
                }
            </div>
        );
    }
}


module.exports = connect( state => ({
    action: state.action,
    user: state.user,
    course : state.course,
    course_work: state.course_work,
    chapter_work: state.chapter_work,
    ppts: state.ppts,
    chapter_progress: state.chapter_progress,
    video_progress: state.video_progress, // 接口device
    video_curm3u8: state.video_m3u8
}) )(Play);
