/*
 * @Author: 吴文洁
 * @Date: 2020-08-05 10:07:47
 * @LastEditors: wufan
 * @LastEditTime: 2021-05-30 20:35:49
 * @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 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)
    }
  }

  //获取分类列表
  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)
  }

  //上传图片
  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
    } = 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 shrink-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}
          />
        )}
        {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 className='tip-box'>
                <div className='tip'>温馨提示</div>
                <div className='tip'>①预览效果图时可能存在延迟，单击左侧图片刷新即可</div>
                <div className='tip'>②设置图片时双击可旋转图片，滚动可放大或缩小图片</div>
              </div>
            </div>
          </div>
        </Modal>
        {this.state.previewCourseModal}
      </div>
    )
  }
}

export default AddVideoCourse
