<template>
  <el-row v-if="!permissionDenied" class="movie-list">
    <el-col v-if="video !== null" :md="15">
      <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <el-row>
              <h3 v-html="video.title" />
            </el-row>
            <el-row style="color: #999;font-size: 16px;padding-top: 0px;">
              <span><i class="el-icon-video-play">{{ video.view }}</i></span>
              <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
              <span><i class="el-icon-s-comment">{{ video.comment }}</i></span>
              <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
              <span><i class="el-icon-watch">{{ video.pubDate }}</i></span>
            </el-row>
          </div>
          <div class="text item">
            <div id="dplayer" ref="dplayer" style="height: 480px;" />
          </div>
        </el-card>
      </el-row>
      <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <div class="video-data-row">
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-collection"
                :disabled="isCollected"
                @click="collection(video.videoId)"
              >
                <span>收藏 {{ video.favorite }}</span>
              </el-button>
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-thumb"
                :disabled="isCollected"
                @click="collection(video.videoId)"
              >
                <span>喜欢 {{ video.thumbUp }}</span>
              </el-button>
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-share"
                :disabled="isCollected"
                @click="collection(video.videoId)"
              >
                <span>分享 {{ video.share }}</span>
              </el-button>
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-download"
                @click="getDownloadUrl(video.videoId)"
              >
                <span>下载</span>
              </el-button>
              <el-button
                v-if="video.cache != null"
                type="danger"
                size="mini"
                icon="el-icon-download"
                @click="cacheBiliVideo(video.videoId)"
              >
                <span>{{ video.cache.msg }}</span>
              </el-button>
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-help"
                @click="displayErrorReportDialog"
              >
                <span>报错</span>
              </el-button>
            </div>
          </div>
          <div class="text item">
            <!--视频描述行-->
            <span class="description" v-html="video.description" />
            <el-divider />
            <!--视频标签行-->
            <div class="v-tag">
              <el-tag
                v-for="(tag,index) in video.tags"
                :key="index"
                class="tag"
                size="medium"
                effect="plain"
              >
                <router-link target="_blank" :to="`/video/tag/` + tag">
                  {{ tag }}
                </router-link>
              </el-tag>
            </div>
          </div>
        </el-card>
      </el-row>
      <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <el-row>
              <h3>视频评论</h3>
            </el-row>
          </div>
          <div class="text item">
            <div ref="comment" :style="wrapStyle" class="comment-wrap">
              <comment
                v-model="videoComments"
                :user="currentUser"
                :props="props"
                :before-submit="submit"
                :before-like="like"
                :before-delete="deleteComment"
                :upload-img="uploadImg"
              />
            </div>
          </div>
        </el-card>
      </el-row>
    </el-col>
    <el-col :md="9">
      <el-row>
        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
          <user-avatar-card v-if="user !== null" :user-avatar="user" />
        </el-row>
        <el-row v-if="showPlaylist" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <el-row>
                <h3>播放列表</h3>
              </el-row>
              <el-row>
                <span>自动播放 <el-switch v-model="autoPlay" /></span>
              </el-row>
            </div>
            <div class="text item">
              <el-table
                :data="playList.list"
                :show-header="false"
                height="480"
                style="width: 100%"
              >
                <el-table-column
                  prop="title"
                >
                  <template slot-scope="scope">
                    <router-link :to="`/vidlist/${scope.row.videoId}`">
                      <span>{{ scope.row.title | ellipsis }}</span>
                    </router-link>
                  </template>
                </el-table-column>
                <el-table-column
                  prop="duration"
                >
                  <template slot-scope="scope">
                    <span>{{ scope.row.duration }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-card>
        </el-row>
      </el-row>
    </el-col>

    <!-- 视频访问码对话框 -->
    <el-dialog
      append-to-body
      :visible.sync="showAccessCodeDialog"
      width="30%"
      center
    >
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>输入视频访问码</span>
          <el-button style="float: right; padding: 3px 0" type="text" @click="submitAccessCodeWrapper">提交</el-button>
        </div>
        <div class="text item">
          <el-form ref="form" :model="accessCodeForm" label-width="80px">
            <el-form-item label="访问码">
              <el-input v-model="accessCodeForm.accessCode" style="width: 70%; padding-right: 2px" />
            </el-form-item>
          </el-form>
        </div>
      </el-card>
    </el-dialog>

    <!-- 视频报错对话框 -->
    <el-dialog
      append-to-body
      :visible.sync="showErrorReportDialog"
      width="30%"
      center
    >
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>视频报错</span>
          <el-button style="float: right; padding: 3px 0" type="text" @click="submitErrorReport">提交错误</el-button>
        </div>
        <div class="text item">
          <el-form ref="form" :model="errorReportForm" label-width="80px">
            <el-form-item label="错误类型">
              <el-select v-model="errorReportForm.errorCode" placeholder="选择视频错误类型">
                <el-option label="视频无封面" value="1" />
                <el-option label="视频无声音" value="2" />
                <el-option label="视频无画面" value="3" />
                <el-option label="视频无资源" value="4" />
                <el-option label="视频待删除" value="5" />
              </el-select>
            </el-form-item>
          </el-form>
        </div>
      </el-card>
    </el-dialog>
  </el-row>
  <el-row v-else>
    <permission-denied-card :text-object="textObject" />
  </el-row>
</template>

<script>
import PermissionDeniedCard from '@/components/card/PermissionDeniedCard'
import UserAvatarCard from '@/components/card/UserAvatarCard'
import comment from '@/components/comment'
import SocketInstance from '@/utils/ws/socket-instance'

import flvjs from 'flv.js'
import DPlayer from 'dplayer'

import { videoUrl, similarVideo, videoInfo, videoErrorReport, downloadVideo, cacheBiliVideo } from '@/api/video'
import { collectItem } from '@/api/collect'
import { getUserInfo } from '@/api/user'
import { submitAccessCode } from '@/api/content'
import { getAccessToken } from '@/utils/auth'

export default {
  name: 'VideoList',
  components: { UserAvatarCard, PermissionDeniedCard, comment },
  filters: {
    ellipsis(value) {
      if (!value) return ''
      const max = 20
      if (value.length > max) {
        return value.slice(0, max) + '...'
      }
      return value
    }
  },
  data() {
    return {
      /** ********************************************************************/
      wrapStyle: '',
      videoComments: [],
      currentUser: {
        name: '草莓',
        avatar: '//picx.zhimg.com/v2-a2c89378a6332cbfed3e28b5ab84feb7.jpg'
      },
      props: {
        id: 114511,
        content: 'this is comment content',
        imgSrc: '',
        children: [],
        likes: 0,
        liked: false,
        reply: null,
        createAt: 'createAt',
        user: {
          name: '芒果',
          avatar: ''
        }
      },
      // **********************************************************************/
      video: null,
      user: null,
      isCollected: false,
      showAccessCodeDialog: false,
      accessCodeForm: {
        contentId: null,
        contentType: 1002,
        accessCode: null
      },
      showErrorReportDialog: false,
      errorReportForm: {
        videoId: null,
        errorCode: null
      },
      permissionDenied: false,
      textObject: {
        content: '视频',
        route: '/video'
      },
      showPlaylist: true,
      autoPlay: false,
      playList: {
        current: 0,
        list: [
          'eyNXaDnmN3',
          'WkYNYzDePp',
          'a8Vx9EGDbA',
          'a8V3D88NJK',
          '4m7qMXapp1'
        ]
      },
      // **********************************************************************/
      flvjs,
      DPlayer,
      danmaku: {
        api: process.env.VUE_APP_SERVER_URL + '/api/comment/danmaku/',
        token: 'tnbapp'
      },
      getUrl: true
    }
  },
  watch: {
    // 地址栏 url 发生变化时重新加载本页面
    $route() {
      this.$router.go()
    }
  },
  created() {
    const videoId = this.$route.params.id
    this.accessCodeForm.contentId = videoId
    this.getVideoInfo(videoId)

    const key = 'myplaylist-' + videoId
    const value = localStorage.getItem(key)
    if (value != null) {
      this.playList = JSON.parse(value)
      this.calculateCurrent(videoId)
    } else {
      this.getSimilarVideos(videoId)
    }
  },
  mounted() {
    window.addEventListener('beforeunload', this.handleBeforeUnload)
    const header = this.$refs.header
    if (header !== undefined && header !== null) {
      console.log('header -> ' + header)
      this.wrapStyle = `height: calc(100vh - ${header.clientHeight + 20}px)`
    }
  },
  methods: {
    handleBeforeUnload(event) {
      const key = 'myplaylist-' + this.video.videoId
      localStorage.removeItem(key)
      // event.preventDefault()
    },
    // 获取视频的详细信息
    getVideoInfo(videoId) {
      videoInfo(videoId).then(resp => {
        if (resp.code === 0) {
          // this.showAccessCodeDialog = true
          this.video = resp.data
          document.title = resp.data.title
          this.getVideoUrl(videoId)

          this.userId = resp.data.userId
          getUserInfo(this.userId).then(resp => {
            if (resp.code === 0) {
              this.user = resp.data
            } else {
              this.$notify.error({
                message: '用户数据获取失败',
                type: 'warning',
                duration: 3000
              })
            }
          })
        } else if (resp.code === 2) {
          this.$router.push('/404')
        } else {
          this.permissionDenied = true
        }
      }).catch(error => {
        this.$notify.error({
          message: error.message,
          type: 'warning',
          duration: 3000
        })
      })
    },
    // 获取和当前视频类似的其他视频
    getSimilarVideos(videoId) {
      similarVideo(videoId).then(resp => {
        if (resp.code === 0) {
          this.playList.list = resp.data
          this.calculateCurrent(videoId)
        } else {
          this.$notify.error({
            message: '推荐视频数据获取失败',
            type: 'warning',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify.error({
          message: error.message,
          type: 'warning',
          duration: 3000
        })
      })
    },
    // 换一换
    refreshSimilar() {
      console.log('刷新相关推荐')
    },
    // 用户点击收藏
    collection(videoId) {
      const jsonData = {}
      jsonData.contentType = 1002
      jsonData.contentId = videoId
      jsonData.collected = true
      collectItem(jsonData).then(resp => {
        if (resp.code !== 0) {
          this.$notify.success({
            title: '视频收藏失败',
            type: 'warning',
            duration: 3000
          })
        }
      })
    },
    getDownloadUrl(videoId) {
      // let filename
      downloadVideo(videoId).then(resp => {
        if (resp.code === 0) {
          const downloadUrl = resp.data.url
          window.open(downloadUrl, '_blank')
        } else {
          this.$notify({
            title: '提示',
            message: resp.msg,
            type: 'warning',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify({
          title: '提示',
          message: error.message,
          type: 'error',
          duration: 3000
        })
      })
    },
    cacheBiliVideo(bvId) {
      cacheBiliVideo(bvId).then(resp => {
        if (resp.code === 0) {
          const resData = resp.data
          this.$notify({
            title: '提示',
            message: resData.msg,
            type: 'warning',
            duration: 3000
          })
        }
      })
    },
    submitAccessCodeWrapper() {
      submitAccessCode(this.accessCodeForm).then(resp => {
        if (resp.code === 0) {
          this.video = resp.data
        } else {
          this.$notify({
            message: resp.msg,
            type: 'warning',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify({
          title: '提示',
          message: error.message,
          type: 'warning',
          duration: 3000
        })
      })
    },
    displayErrorReportDialog() {
      this.errorReportForm.videoId = this.video.videoId
      this.showErrorReportDialog = true
    },
    submitErrorReport() {
      this.showErrorReportDialog = false
      videoErrorReport(this.errorReportForm).then(resp => {
        if (resp.code === 0) {
          this.$notify({
            title: '提示',
            message: '视频错误已提交',
            type: 'warning',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify({
          title: '提示',
          message: error.message,
          type: 'warning',
          duration: 3000
        })
      })
    },
    // ****************************************************************************************************************
    getVideoUrl(videoId) {
      videoUrl(videoId).then(res => {
        if (res.code === 0) {
          const token = getAccessToken()
          if (token != null) {
            SocketInstance.connect()
          }

          const urlType = res.data.type
          if (urlType === 'mp4') {
            const urls = res.data.urls
            for (const url of urls) {
              url.type = 'normal'
            }
            this.initMp4Player(this.video.userId, videoId, this.video.coverUrl, urls, res.data.currentTime)
          } else {
            this.$notify.error({
              message: '视频 url 类型不合法',
              type: 'warning',
              duration: 3000
            })
          }
        } else {
          this.$notify.error({
            message: '视频 url 获取失败',
            type: 'warning',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify.error({
          message: error.message,
          type: 'error',
          duration: 3000
        })
      })
    },
    initMp4Player(userId, videoId, coverUrl, urls, pos) {
      const player = new DPlayer({
        container: document.querySelector('#dplayer'),
        lang: 'zh-cn',
        screenshot: false,
        autoplay: false,
        volume: 0.1,
        mutex: true,
        video: {
          pic: coverUrl,
          defaultQuality: 0,
          quality: urls,
          hotkey: true
        },
        danmaku: {
          id: videoId,
          maximum: 10000,
          api: this.danmaku.api,
          token: this.danmaku.token,
          user: userId,
          bottom: '15%',
          unlimited: true
        }
      })

      // 设置音量
      // player.volume(0.1, true, false)
      // 跳转到上次看到的位置
      player.seek(pos)

      /* 事件绑定 */
      player.on('progress', function() {
        const jsonData = {}
        jsonData.videoId = videoId
        jsonData.currentTime = player.video.currentTime
        SocketInstance.send(jsonData)
      })

      player.on('ended', () => {
        const jsonData = {}
        jsonData.videoId = videoId
        jsonData.currentTime = player.video.currentTime
        SocketInstance.send(jsonData)
        this.getNextPath(videoId)
      })

      player.on('volumechange', () => {
        console.log('声音改变')
      })
    },
    calculateCurrent(videoId) {
      for (var i = 0; i < this.playList.list.length; i++) {
        if (videoId === this.playList.list[i].videoId) {
          this.playList.current = i
          const key = 'myplaylist-' + this.video.videoId
          localStorage.setItem(key, JSON.stringify(this.playList))
        }
      }
    },
    setCurrent(current) {
      this.playList.current = current
      const key = 'myplaylist-' + this.video.videoId
      localStorage.setItem(key, JSON.stringify(this.playList))
    },
    getNextPath(current) {
      this.calculateCurrent(current)
      const next = this.playList.current + 1
      if (next < this.playList.list.length) {
        this.setCurrent(next)
        const videoId = this.playList.list[next].videoId
        const path = '/vidlist/' + videoId
        if (path !== this.$route.path) {
          this.$router.push(path)
        } else {
          console.log(this.playList)
          this.$notify.info({
            message: '视频列表播放完成',
            duration: 3000
          })
        }
      }
    },
    // ****************************************************************************************************************
    async submit(newComment, parent, add) {
      const res = await new Promise((resolve) => {
        setTimeout(() => {
          resolve({ newComment, parent })
        }, 300)
      })
      add(Object.assign(res.newComment, { _id: new Date().getTime() }))
      console.log('addComment: ', res)
    },
    async like(comment) {
      const res = await new Promise((resolve) => {
        setTimeout(() => {
          resolve(comment)
        }, 0)
      })

      console.log('likeComment: ', res)
    },
    async uploadImg({ file, callback }) {
      const res = await new Promise((resolve, reject) => {
        const reader = new FileReader()

        reader.readAsDataURL(file)

        reader.onload = () => {
          resolve(reader.result)
        }

        reader.onerror = () => {
          reject(reader.error)
        }
      })

      callback(res)
      console.log('uploadImg： ', res)
    },
    async deleteComment(comment, parent) {
      const res = await new Promise((resolve) => {
        setTimeout(() => {
          resolve({ comment, parent })
        }, 300)
      })
      console.log('deleteComment: ', res)
    }
  }
}
</script>

<style scoped>
/*处于手机屏幕时*/
@media screen and (max-width: 768px) {
  .movie-list {
    padding-top: 8px;
    padding-left: 0.5%;
    padding-right: 0.5%;
  }
}

.movie-list {
  padding-top: 15px;
  padding-left: 5%;
  padding-right: 5%;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both;
}

.v-tag {
  padding-top: 10px;
}
.tag{
  margin-right: 3px;
}
</style>
