/*
 * @Author: 吴文洁
 * @Date: 2020-08-05 10:07:47
 * @LastEditors: yuananting
 * @LastEditTime: 2021-03-24 19:34:37
 * @Description: 视频课新增/编辑页
 * @Copyright: 杭州杰竞科技有限公司 版权所有
 */

import React from 'react';
import { Button, Input, Radio, message, Modal,Cascader} from 'antd';

import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum';
import { ImgCutModalNew } from '@/components';
import ShowTips from "@/components/ShowTips";
import Breadcrumbs from "@/components/Breadcrumbs";

import AddVideoIntro from './components/AddVideoIntro';
import SelectStudent from '../modal/select-student';
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal';
import PreviewCourseModal from '../modal/PreviewCourseModal';
import StoreService from "@/domains/store-domain/storeService";
import CourseService from "@/domains/course-domain/CourseService";
import Service from '@/common/js/service';
import User from '@/common/js/user';
import _ from "underscore";
import Upload from '@/core/upload';
import { randomString } from '@/domains/basic-domain/utils';
import $ from 'jquery';
import Bus from '../../../core/bus'
// import PhotoClip from 'photoclip';
import './AddVideoCourse.less';

const EDIT_BOX_KEY = Math.random();
const fieldNames  = { label: 'categoryName', value: 'id', children: 'sonCategoryList' };

//添加课程时课程默认的一些值
const defaultShelfState = 'YES';
const defaultScheduleMedia = [{          
  contentType:'INTRO',
  mediaType: 'TEXT',
  mediaContent: '',
  key: EDIT_BOX_KEY
}]
const whetherVisitorsJoin = 'NO'

let cutFlag = false;
class AddVideoCourse extends React.Component {

  constructor(props) {
    super(props);

    const id = getParameterByName("id");
    const pageType = getParameterByName("type");

    this.state = {
      id,                        // 视频课ID,编辑的时候从URL上带过来
      pageType,                  // 页面类型: add->新建 edit->编辑
      imageFile: null,           // 需要被截取的图片
      courseName: null,        // 视频课名称
      scheduleVideoId: null,     // 视频课链接
      coverId: null,             // 视频封面的recourceId
      coverUrl: null,            // 视频课封面
      studentList: [],           // 上课学员列表
      shelfState:'YES',          //是否开启学院展示
      scheduleMedia: [{          // 视频课媒体资源
        contentType:"INTRO",
        mediaType: 'TEXT',
        mediaContent: '',
        key: EDIT_BOX_KEY
      }],
      diskList: [],              // 机构可见磁盘目录
      selectedFileList: [],      // 已经从资料云盘中勾选的文件
      showCutModal: false,       // 是否显示截图弹窗
      showSelectFileModal: false,
      studentModal: false,
      categoryName:null, //分类名称
      courseCatalogList:[], //分类列表
      categoryId:null, //分类的Id值
      whetherVisitorsJoin:'NO', // 是否允许游客加入
      showSelectCoverModal:false,
      cutImageBlob: null,
      introduce: '',
    }
  }

  componentWillMount() {
    const { id, pageType } = this.state;
    this.getCourseCatalogList();
    if (pageType === 'edit') {
      this.handleFetchScheudleDetail(id);
    }
    this.initBus()
  }

  initBus = () => {
    Bus.bind('graphicsEditorImage', this.uploadIntroImage)
  }

  removeBus = () => {
    Bus.unbind('graphicsEditorImage', this.uploadIntroImage)
  }

  uploadIntroImage = () => {
    this.setState({ showSelectImageModal: true })
  }

  //获取分类列表
  getCourseCatalogList = ()=>{
    StoreService.getCourseCatalogList({current:1,size:1000}).then((res) => {
        this.setState({
          courseCatalogList:res.result.records
        })
    });
  }
  
  catalogChange= (value) => {
    const changeValueLength = value.length;
    switch (changeValueLength){
      case 1:
        this.setState({categoryId:value[0]});   
      break;
      case 2:
        this.setState({categoryId:value[1]});
      break;
      default:
        this.setState({categoryId:null});
      break;    
    }
  }
  // 获取视频课详情
  handleFetchScheudleDetail = (courseId) => {
    CourseService.videoScheduleDetail({
      courseId
    }).then((res) => {
      const { result = {} } = res || {};
      const {
        courseName,
        shelfState,
        whetherVisitorsJoin,
        courseMediaVOS,
        categoryOneName,
        categoryTwoName,
        categoryId
      } = result;
        let coverId;
        let coverUrl;
        let videoType;
        let videoDuration;
        let videoName;
        let scheduleMedia = [];
        let scheduleVideoId;
        let scheduleVideoUrl;
      let hasIntro;
        
        courseMediaVOS.map((item) => {
          switch (item.contentType){
            case "COVER":
              coverId = item.mediaContent;
              coverUrl = item.mediaUrl;
            break;
            case "SCHEDULE":
              videoDuration = item.videoDuration;
              videoName = item.mediaName;
              scheduleVideoId = item.mediaContent;
              scheduleVideoUrl = item.mediaUrl;
              videoType = item.mediaType;
            break;
            case "INTRO":
              hasIntro = true;
              this.getTextDetail('introduce', item.mediaUrl);
            break;  
            default:
            break;
          }
          return item;
        })
      
      let  categoryName;
      if( categoryTwoName ){
        categoryName = `${categoryOneName}-${categoryTwoName}`;
      }else{
        categoryName = `${categoryOneName}`;
      }
      this.setState({
        loadintroduce: !hasIntro,
        coverId,
        coverUrl,
        videoType,
        videoName,
        videoDuration,
        scheduleMedia,
        courseName,
        scheduleVideoId,
        scheduleVideoUrl,
        shelfState,
        whetherVisitorsJoin,
        categoryName,
        categoryId
      });
    })
  }

  getTextDetail = (key, url) => {
    $.ajax({
      data: {},
      type: 'GET',
      url,
      contentType:'application/x-www-form-urlencoded; charset=UTF-8',
      success: (res) => {
        this.setState({ [key]: res, [`load${key}`]: true });
      }
    })
  }


  handleGoBack = () => {
    const {
      coverId,
      videoName,
      videoDuration,
      courseName,
      scheduleMedia, 
      scheduleVideoId,
      categoryId,
      shelfState,
      whetherVisitorsJoin
    } = this.state;
    if(videoName || videoDuration || scheduleVideoId  || !_.isEqual(scheduleMedia, defaultScheduleMedia) || categoryId || courseName || coverId ||  shelfState !== defaultShelfState || whetherVisitorsJoin !== whetherVisitorsJoin ){
      Modal.confirm({
        title: '确认要返回吗?',
        content: '返回后，本次编辑的内容将不被保存。',
        okText: '确认返回',
        cancelText: '留在本页',
        icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
        onOk: () => {
          window.RCHistory.push({
            pathname: `/video-course`,
          });
        }
      });
    }else{
      window.RCHistory.push({
        pathname: `/video-course`,
      });
    }
  }

  // 修改表单
  handleChangeForm = (field, value, coverUrl) => {
    this.setState({
      [field]: value,
      coverUrl: coverUrl ? coverUrl : this.state.coverUrl
    });
  }
  
  // 显示选择学员弹窗
  handleShowSelectStuModal = () => {
    this.setState({ studentModal : true });

    const { studentList, selectedStuList } = this.state;
    const studentModal = (
      <SelectStudent
        showTabs={true}
        type="videoCourse"
        onSelect={this.handleSelectStudent}
        after={true} //表明是不是上课后的状态
        studentList={studentList}
        close={() => {
          this.setState({
            studentModal: null,
          });
        }}
      />
    )
    this.setState({ studentModal });
  }

  handleSelectStudent = (studentIds) => {
    let studentList = [];
    _.each(studentIds, (item) => {
      studentList.push({ studentId: item });
    });
    // this.setState({ studentModal: null });
    this.setState({ studentList  });
    this.setState({ studentModal : false });
  }
  
  // 显示预览弹窗
  handleShowPreviewModal = () => {
    const {
      coverUrl,
      scheduleVideoUrl,
      courseName,
      scheduleMedia,
      videoDuration,
      introduce,
    } = this.state;

    const courseBasinInfo = {
      coverUrl,
      scheduleVideoUrl,
      courseName,
      videoDuration
    }
    const courseIntroInfo = {
      liveCourseMediaRequests: scheduleMedia,
      introduce,
    }

    const previewCourseModal = (
      <PreviewCourseModal
        type="videoCourse"
        courseBasicInfo={courseBasinInfo}
        courseIntroInfo={courseIntroInfo}
        close={() => {
          this.setState({
            previewCourseModal: null
          })
        }}
      />
    );

    this.setState({ previewCourseModal });
  }
  
  // 选择视频
  handleSelectVideo = (file) => {
    this.setState({
      showSelectFileModal: false
    })
    const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file;

    const videoDom = document.createElement('video');
    videoDom.src = ossUrl;
    videoDom.onloadedmetadata = () => {
      this.setState({
        size: folderSize,
        videoName: folderName,
        videoType: folderFormat,
        scheduleVideoUrl: ossUrl,
        scheduleVideoId : resourceId,
        videoDuration: videoDom.duration
      });
    }
  }

  // 保存
  handleSubmit = () => {
    const { instId, adminId } = window.currentUserInstInfo;
    
    const {
      id,
      size,
      coverId,
      coverUrl,
      pageType,
      joinType,
      videoName,
      videoDuration,
      studentList,
      courseName,
      scheduleMedia, 
      scheduleVideoId,
      scheduleVideoUrl,
      categoryId,
      shelfState,
      whetherVisitorsJoin,
      introduce,
    } = this.state;

    const commonParams = {
      videoName,
      videoDuration, 
      courseMediaId: scheduleVideoId,
      scheduleMedia: scheduleMedia.filter(item => !!item.mediaContent),
      categoryId,
      courseName,
      coverId,
      operatorId:User.getStoreUserId(),
      storeId:User.getStoreId(),
      shelfState,
      whetherVisitorsJoin,
      courseType: 'VOICE',
    };
    // 校验必填字段:课程名称, 课程视频
    this.handleValidate(courseName, scheduleVideoId,categoryId, scheduleMedia).then((res) => {
      if (!res) return;
      Upload.uploadTextToOSS(introduce, `${randomString()}.txt`, (introduceId) => {
        this.submitRemote({ id, pageType, commonParams: { ...commonParams, introduceId } })
      });
    });
  }

  submitRemote = ({ id, pageType, commonParams }) => {
    if (pageType === 'add') {
      Service.Hades('public/hades/createMediaCourse', commonParams).then((res) => {
        if (!res) return;
        message.success("新建成功");
        window.RCHistory.push({
          pathname: `/video-course`,
        });
      })
    } else {
      const editParams = {
        courseId:id,
        ...commonParams,
      }
      Service.Hades('public/hades/editMediaCourse', editParams).then((res) => {
        if (!res) return;
        message.success("保存成功");
        window.RCHistory.push({
          pathname: `/video-course`,
        });
      });
    }
  }

  handleValidate = (courseName, scheduleVideoId,categoryId,scheduleMedia) => {
    return new Promise((resolve) => {
      if (!courseName) {
        message.warning('请输入课程名称');
        resolve(false);
        return false
      }  
      if (!scheduleVideoId) {
        message.warning('请上传视频');
        resolve(false);
        return false
      }  
      if(!categoryId){
        message.warning('请选择课程分类');
        resolve(false);
        return false
      }
      const textMedia = scheduleMedia.filter((item) => item.mediaType === 'TEXT');
      for (let i = 0, len = textMedia.length; i < len; i++) {
        if (textMedia[i].mediaContentLength && textMedia[i].mediaContentLength.length > 1000) {
          message.warning(`第${i+1}个文字简介的字数超过了1000个字`);
          resolve(false);
          return false
        }
      }
      resolve(true);
    });
  }
  handleSelectCover = (file)=> {
    this.uploadImage(file);
  }

  handleSelectImage = (file) => {
    this.setState({
      showSelectImageModal: false
    })
    const { ossUrl } = file;
    const { introduce } = this.state;
    this.setState({
      introduce: `${introduce}<p><img style="max-width: 100%;" src="${ossUrl}" /><br/><p>`
    });
  }
  
  //上传图片
  uploadImage = (imageFile) => {
    const { folderName } = imageFile;
    const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
    const self = this;
    this.setState(
      {
        visible: true,
      },
      () => {
        setTimeout(() => {
          const okBtnDom = document.querySelector("#headPicModal");
          const options = {
            size: [500, 282],
            ok: okBtnDom,
            maxZoom: 3,
            style: {
              jpgFillColor: "transparent",
            },
            done: function (dataUrl) {
              clearTimeout(self.timer);
              self.timer = setTimeout(() => {
                if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
                  const _dataUrl = this.clip()
                  const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
                  self.setState({
                    cutImageBlob,
                    dataUrl: _dataUrl,
                    rotate: this.rotate(),
                    scale: this.scale()
                  })
                }

              }, 500)

              const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
              self.setState({
                cutImageBlob,
                dataUrl
              })
              setTimeout(() => {
                cutFlag = false;
              }, 2000);
            },
            fail: (failInfo) => {
              message.error("图片上传失败了，请重新上传");
            },
            loadComplete: function (img) {
              setTimeout(() => {
                const _dataUrl = this.clip()
                self.setState({
                  dataUrl: _dataUrl,
                  hasImgReady: true 
                })
              }, 100)

            },
          };
          const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
          if (!this.state.photoclip) {
            const _photoclip = new PhotoClip("#headPicModal", options);
            _photoclip.load(imgUrl);
            this.setState({
              photoclip: _photoclip,
            });
          } else {
            this.state.photoclip.clear();
            this.state.photoclip.load(imgUrl);
          }

        }, 200);
      }
    );
  };

  //获取resourceId
  getSignature = (blob, fileName) => {
    Upload.uploadBlobToOSS(blob, 'cover' + (new Date()).valueOf(),null,'signInfo').then((signInfo) => {
      this.setState({
        coverClicpPath:signInfo.fileUrl,
        coverId:signInfo.resourceId,
        visible: false
      },()=>this.updateCover())
    
    });
  };
  updateCover = () =>{
    const {coverClicpPath,coverId} = this.state
    this.setState({
      showSelectCoverModal: false,
      coverUrl:coverClicpPath,
      coverId:coverId
    })
  }
   // base64转换成blob
  convertBase64UrlToBlob = (urlData) => {
    const bytes = window.atob(urlData.split(",")[1]);
    const ab = new ArrayBuffer(bytes.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {
      ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], { type: "image/png" });
  };
  render() {
    const {
      pageType,courseName, scheduleVideoId, coverId,
      coverUrl, scheduleVideoUrl, studentList, scheduleMedia,
      showCutModal, showSelectFileModal, diskList,
      imageFile, joinType, videoName, videoType,shelfState,
      categoryName,courseCatalogList,whetherVisitorsJoin,
      visible,showSelectCoverModal,hasImgReady,cutImageBlob,
      introduce,
      loadintroduce,
      id,
      showSelectImageModal,
    } = this.state;

    // 已选择的上课学员数量
    const hasSelectedStu = studentList.length;

    const courseWareIcon = FileVerifyMap[videoType] ? FileTypeIcon[FileVerifyMap[videoType].type] : FileTypeIcon[videoType];
    
    return (
      <div className="page add-video-course-page">
        <Breadcrumbs
          navList={pageType === "add" ? "新建视频课" : "编辑视频课"}
          goBack={this.handleGoBack}
        />

        <div className="box">
          <div className="show-tips">
            <ShowTips message="请遵守国家相关规定，切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容，小麦企培保有依据国家规定及平台规则进行处理的权利" />
          </div>

          <div className="form">
            <div className="course-name required">
              <span className="label">课程名称：</span>
              <Input
                value={courseName}
                placeholder="请输入视频课的名称（40字以内）"
                maxLength={40}
                style={{ width: 240 }}
                onChange={(e) => { this.handleChangeForm('courseName', e.target.value)}}
              />
            </div>

            <div className="upload-video mt16">
              <div className="content flex">
                <span className="label required">视频上传：</span>
                <div className="value">
                  {
                    scheduleVideoId ?
                    <div className="course-ware">
                      <img  className="course-ware__img" src={courseWareIcon} />
                      <span className="course-ware__name">{videoName}</span>
                    </div> :
                    <div className="course-ware--empty">从资料云盘中选择视频</div>
                  }
                  
                </div>
              </div>
              <div className="sub-content">
                <Button
                  onClick={() => {
                    this.setState({
                      showSelectFileModal: true
                    })
                  }}
                >{`${(pageType === 'add' && !scheduleVideoId) ? '选择' : '更换'}视频`}</Button>

                <span className="tips">视频数量限制1个，大小不超过2G</span>
              </div>
            </div>

            <div className="cover-url flex mt16">
              <div className="label">视频封面：</div>
              <div className="cover-url__wrap">
                <div className="img-content">
                  {/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */}
                  {
                    (scheduleVideoUrl || coverUrl )?
                    <img src={coverUrl || `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`} /> :
                    <div className="empty-img">若不上传<br />系统默认将视频首帧作为封面图</div>
                  }
                </div>
                <div className="opt-btns">
                  <Button onClick={() => {this.setState({ showSelectCoverModal:true  })}}>{`${(pageType === 'add' && (!scheduleVideoId && !coverUrl)) ? '上传' : '修改'}封面`}</Button>
                  <div className="tips">建议尺寸1280*720px或16:9。封面图最大5M，支持jpg、jpeg和png。</div>
                </div>
              </div>
            </div>
            <div className="course-catalog required">
              <span className="label">课程分类：</span>
              { (pageType === 'add') && 
                <Cascader defaultValue={[categoryName]} options={courseCatalogList} displayRender={	label => label.join('-')}  fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类"  suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>}/>
              }
              { (pageType === 'edit' && categoryName ) && 
                <Cascader defaultValue={[categoryName]} options={courseCatalogList} displayRender={	label => label.join('-')}  fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>}/>
              }
            </div>
            <div className="intro-info mt16">
              <AddVideoIntro
                data={{
                  id,
                  liveCourseMediaRequests: scheduleMedia,
                  shelfState,
                  whetherVisitorsJoin,
                  introduce,
                  loadintroduce,
                }}
                onChange={this.handleChangeForm}
              />
            </div>
          </div>
        </div>

        <div className="footer">
          <Button onClick={this.handleGoBack}>取消</Button>
          <Button onClick={this.handleShowPreviewModal}>预览</Button>
          <Button type="primary" onClick={_.debounce(() => this.handleSubmit(), 3000, true)}>保存</Button>
        </div>
        
        {/* 选择备课文件弹窗 */}
        { showSelectFileModal &&
          <SelectPrepareFileModal
            operateType="select"
            selectTypeList={['MP4']}
            accept="video/mp4"
            confirm={{
              title: '文件过大，无法上传',
              content: '为保障学员的观看体验，上传的视频大小不能超过2G',
            }}
            tooltip={'格式支持mp4，大小不超过2G'}
            isOpen={showSelectFileModal}
            diskList={diskList}
            addVideo={true}
            onClose={() => {
              this.setState({ showSelectFileModal: false })
            }}
            onSelect={this.handleSelectVideo}
          />
        }
        {showSelectImageModal && 
          <SelectPrepareFileModal
            key="basic"
            operateType="select"
            multiple={false}
            accept="image/jpeg,image/png,image/jpg"
            selectTypeList={['JPG', 'JPEG', 'PNG']}
            tooltip='支持文件类型：jpg、jpeg、png'
            isOpen={showSelectImageModal}
            onClose={() => {
              this.setState({ showSelectImageModal: false })
            }}
            onSelect={this.handleSelectImage}
          />
        }
         {showSelectCoverModal && 
          <SelectPrepareFileModal
            key="basic"
            operateType="select"
            multiple={false}
            accept="image/jpeg,image/png,image/jpg"
            selectTypeList={['JPG', 'JPEG', 'PNG']}
            tooltip='支持文件类型：jpg、jpeg、png'
            isOpen={showSelectCoverModal}
            onClose={() => {
              this.setState({ showSelectCoverModal: false })
            }}
            onSelect={this.handleSelectCover}
          />
        }
        <Modal
          title="设置图片"
          width={1080}
          visible={visible}
          maskClosable={false}
          closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
          onCancel={() => {
            this.setState({ visible: false });
          }}
          zIndex={10001}
          footer={[
            <Button
              key="back"
              onClick={() => {
                this.setState({ visible: false });
              }}
            >
              重新上传
            </Button>,
            <Button
              key="submit"
              type="primary"
              disabled={!hasImgReady}
              onClick={() => {
                if (!cutFlag) {
                  cutFlag = true;
                  this.refs.hiddenBtn.click();
                }
                this.getSignature(cutImageBlob);
              }}
            >
              确定
            </Button>,
          ]}
        >
          <div className="clip-box">
            <div
              id="headPicModal"
              ref="headPicModal"
              style={{
                width: "500px",
                height: "430px",
                marginBottom: 0,
              }}
            ></div>
            <div id="clipBtn" style={{ display: "none" }} ref="hiddenBtn"></div>
            <div className="preview-img">
              <div className="title">效果预览</div>
              <div id="preview-url-box" style={{width:500,height:282}}>
                <img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
              </div>
            </div>
          </div>
        </Modal>
        { this.state.previewCourseModal }
      </div>
    )
  }
}

export default AddVideoCourse;
