<template>
  <div class="listpage" id="star">
    <div class="listpage-header" id="star-header">
        <el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
        <el-button @click.stop="exportFavoritesEvent" icon="el-icon-upload2">导出</el-button>
        <el-button @click.stop="importFavoritesEvent" icon="el-icon-download">导入</el-button>
        <el-button @click.stop="clearFavoritesEvent" icon="el-icon-delete-solid">清空</el-button>
        <el-button @click.stop="updateAllEvent" icon="el-icon-refresh">同步所有收藏</el-button>
    </div>
    <div class="listpage-body" id="star-body">
      <div class="show-table" id="star-table"  v-show="viewMode === 'list'">
        <el-table size="mini" fit height="100%" row-key="id"
        ref="starTable"
        :data="list"
        :cell-class-name="checkUpdate"
        @row-click="detailEvent"
        @sort-change="handleSortChange">
          <el-table-column
            sortable
            :sort-method="sortByName"
            prop="name"
            label="片名">
          </el-table-column>
          <el-table-column
            prop="site.name"
            width="120"
            label="源站">
            <template slot-scope="scope">
              <span>{{ getSiteName(scope.row) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            :sort-by="['detail.type', 'name']"
            sortable
            :sort-method="sortByType"
            prop="detail.type"
            label="类型"
            width="100">
          </el-table-column>
          <el-table-column
            sortable
            :sort-by="['detail.year', 'name']"
            prop="detail.year"
            label="上映"
            width="100"
            align="center">
          </el-table-column>
          <el-table-column v-if="list.some(e => e.detail.note)"
            prop="detail.note"
            width="120"
            label="备注">
          </el-table-column>
          <el-table-column v-if="list.some(e => e.rate)"
            prop="rate"
            width="120"
            label="豆瓣评分">
          </el-table-column>
          <el-table-column v-if="list.some(e => e.index >= 0)"
            prop="index"
            width="120"
            label="观看至">
            <template slot-scope="scope">
              <span>{{ getHistoryNote(scope.row.index) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            header-align="right"
            align="right">
            <template slot-scope="scope">
              <el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
              <el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
              <el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
              <el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
        <Waterfall ref="starWaterfall" :list="list" :gutter="20" :width="240"
          :breakpoints="{
            1200: { //当屏幕宽度小于等于1200
              rowPerView: 4,
            },
            800: { //当屏幕宽度小于等于800
              rowPerView: 3,
            },
            500: { //当屏幕宽度小于等于500
              rowPerView: 2,
            }
          }"
          animationEffect="fadeInUp"
          backgroundColor="rgba(0, 0, 0, 0)">
            <template slot="item" slot-scope="props">
              <div class="card">
                <div class="img">
                  <div class="rate" v-if="props.data.rate && props.data.rate !== '暂无评分'">
                    <span>{{props.data.rate}}分</span>
                  </div>
                  <div class="update" v-if="props.data.hasUpdate">
                    <span>有更新</span>
                  </div>
                  <div class="progress" v-if="props.data.index && props.data.detail && props.data.detail.m3u8List !== undefined && props.data.detail.m3u8List.length > 1">
                  <span>
                    看至第{{ props.data.index + 1 }}集
                  </span>
                  </div>
                  <img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.starWaterfall.refresh()" @click="detailEvent(props.data)">
                  <div class="operate">
                    <div class="operate-wrap">
                      <span class="o-play" @click="playEvent(props.data)">播放</span>
                      <span class="o-share" @click="shareEvent(props.data)">分享</span>
                      <span class="o-star" @click="downloadEvent(props.data)">下载</span>
                      <span class="o-star" @click="deleteEvent(props.data)">删除</span>
                    </div>
                  </div>
                </div>
                <div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
                <div class="info">
                  <span>{{props.data.detail.area}}</span>
                  <span>{{props.data.detail.year}}</span>
                  <span>{{props.data.detail.note}}</span>
                  <span>{{props.data.detail.type}}</span>
                </div>
              </div>
            </template>
        </Waterfall>
      </div>
    </div>
  </div>
</template>
<script>
import { mapMutations } from 'vuex'
import { star, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import { remote } from 'electron'
import fs from 'fs'
import Sortable from 'sortablejs'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
  name: 'star',
  data () {
    return {
      list: [],
      sites: [],
      viewMode: 'picture',
      numNoUpdate: 0
    }
  },
  components: {
    Waterfall
  },
  computed: {
    view: {
      get () {
        return this.$store.getters.getView
      },
      set (val) {
        this.SET_VIEW(val)
      }
    },
    video: {
      get () {
        return this.$store.getters.getVideo
      },
      set (val) {
        this.SET_VIDEO(val)
      }
    },
    detail: {
      get () {
        return this.$store.getters.getDetail
      },
      set (val) {
        this.SET_DETAIL(val)
      }
    },
    share: {
      get () {
        return this.$store.getters.getShare
      },
      set (val) {
        this.SET_SHARE(val)
      }
    }
  },
  watch: {
    view () {
      if (this.view === 'Star') {
        this.getAllsites()
        this.getFavorites()
        this.$refs.starWaterfall.refresh()
      }
    },
    numNoUpdate () {
      // 如果所有收藏都没有更新的话
      if (this.numNoUpdate === this.list.length) {
        this.numNoUpdate = 0
        this.$message.warning('未查询到任何更新')
      }
    }
  },
  methods: {
    ...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
    handleSortChange (column, prop, order) {
      this.updateDatabase()
    },
    sortByName (a, b) {
      return a.name.localeCompare(b.name, 'zh')
    },
    sortByType (a, b) {
      return a.type.localeCompare(b.type)
    },
    detailEvent (e) {
      this.detail = {
        show: true,
        key: e.key,
        info: {
          id: e.ids,
          name: e.name
        }
      }
      if (e.hasUpdate) {
        this.clearHasUpdateFlag(e)
      }
    },
    async playEvent (e) {
      if (e.index) {
        this.video = { key: e.key, info: { id: e.ids, name: e.name, index: e.index }, detail: e.detail }
      } else {
        this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 }, detail: e.detail }
      }
      if (e.hasUpdate) {
        this.clearHasUpdateFlag(e)
      }
      this.view = 'Play'
    },
    deleteEvent (e) {
      star.remove(e.id).then(res => {
        if (res) {
          this.$message.warning('删除失败')
        } else {
          this.$message.success('删除成功')
        }
        this.getFavorites()
      })
    },
    shareEvent (e) {
      this.share = {
        show: true,
        key: e.key,
        info: e
      }
    },
    checkUpdate ({ row, rowIndex }) {
      if (this.list[rowIndex].hasUpdate) {
        return 'highlight'
      }
    },
    async clearHasUpdateFlag (e) {
      const db = await star.find({ id: e.id })
      if (db) {
        db.hasUpdate = false
        star.update(e.id, db)
        this.getFavorites()
      }
    },
    updateEvent (e) {
      zy.detail(e.key, e.ids).then(detailRes => {
        var doc = {
          id: e.id,
          key: e.key,
          ids: e.ids,
          site: e.site,
          name: e.name,
          detail: detailRes,
          index: e.index
        }
        star.get(e.id).then(resStar => {
          if (!e.hasUpdate && e.detail.last !== detailRes.last) {
            doc.hasUpdate = true
            var msg = `同步"${e.name}"成功, 检查到更新。`
            this.$message.success(msg)
          } else {
            this.numNoUpdate += 1
          }
          star.update(e.id, doc)
          this.getFavorites()
        })
      }).catch(err => {
        var msg = `同步"${e.name}"失败, 请重试。`
        this.$message.warning(msg, err)
      })
    },
    updateAllEvent () {
      this.numNoUpdate = 0
      this.list.forEach(e => {
        this.updateEvent(e)
      })
    },
    downloadEvent (e) {
      zy.download(e.key, e.ids).then(res => {
        if (res && res.dl && res.dl.dd) {
          const text = res.dl.dd._t
          if (text) {
            const list = text.split('#')
            let downloadUrl = ''
            for (const i of list) {
              const url = encodeURI(i.split('$')[1])
              downloadUrl += (url + '\n')
            }
            clipboard.writeText(downloadUrl)
            this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
          } else {
            this.$message.warning('没有查询到下载链接.')
          }
        } else {
          var m3u8List = {}
          zy.detail(e.key, e.ids).then(res => {
            const dd = res.dl.dd
            const type = Object.prototype.toString.call(dd)
            if (type === '[object Array]') {
              for (const i of dd) {
                if (i._flag.indexOf('m3u8') >= 0) {
                  m3u8List = i._t.split('#')
                }
              }
            } else {
              m3u8List = dd._t.split('#')
            }
            const list = [...m3u8List]
            let downloadUrl = ''
            for (const i of list) {
              const url = encodeURI(i.split('$')[1])
              downloadUrl += (url + '\n')
            }
            clipboard.writeText(downloadUrl)
            this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
          })
        }
      })
    },
    getSiteName (row) {
      if (row.site) {
        return row.site.name
      } else {
        var site = this.sites.find(e => e.key === row.key)
        if (site) {
          return site.name
        }
      }
    },
    getHistoryNote (index) {
      if (index !== null && index !== undefined) {
        return `第${index + 1}集`
      } else {
        return ''
      }
    },
    getFavorites () {
      star.all().then(res => {
        this.list = res.sort(function (a, b) {
          return b.id - a.id
        })
      })
    },
    getAllsites () {
      sites.all().then(res => {
        this.sites = res
      })
    },
    exportFavoritesEvent () {
      const arr = [...this.list]
      const str = JSON.stringify(arr, null, 2)
      const options = {
        filters: [
          { name: 'JSON file', extensions: ['json'] },
          { name: 'Normal text file', extensions: ['txt'] },
          { name: 'All types', extensions: ['*'] }
        ]
      }
      remote.dialog.showSaveDialog(options).then(result => {
        if (!result.canceled) {
          fs.writeFileSync(result.filePath, str)
          this.$message.success('导出收藏成功')
        }
      }).catch(err => {
        this.$message.error(err)
      })
    },
    importFavoritesEvent () {
      const options = {
        filters: [
          { name: 'JSON file', extensions: ['json'] },
          { name: 'Normal text file', extensions: ['txt'] },
          { name: 'All types', extensions: ['*'] }
        ],
        properties: ['openFile', 'multiSelections']
      }
      remote.dialog.showOpenDialog(options).then(result => {
        if (!result.canceled) {
          var starList = Array.from(this.list)
          var id = this.list.length + 1
          result.filePaths.forEach(file => {
            var str = fs.readFileSync(file)
            const json = JSON.parse(str)
            json.reverse().forEach(ele => {
              const starExists = starList.some(x => x.key === ele.key && x.ids === ele.ids)
              if (!starExists) {
                var doc = {
                  id: id,
                  key: ele.key,
                  ids: ele.ids,
                  site: ele.site === undefined ? ele.site = this.sites.find(x => x.key === ele.key) : ele.site,
                  name: ele.name,
                  hasUpdate: ele.hasUpdate,
                  index: ele.index,
                  rate: ele.rate,
                  detail: ele.detail === undefined ? {
                    director: ele.director,
                    actor: ele.actor,
                    type: ele.type,
                    area: ele.area,
                    lang: ele.lang,
                    year: ele.year,
                    last: ele.last,
                    note: ele.note
                  } : ele.detail
                }
                id += 1
                starList.push(doc)
              }
            })
          })
          star.clear().then(star.bulkAdd(starList).then(res => {
            this.getFavorites()
            this.$message.success('导入收藏成功')
          }))
        }
      }).catch(err => {
        this.$message.error(err)
      })
    },
    clearFavoritesEvent () {
      star.clear().then(e => {
        this.getFavorites()
      })
    },
    syncTableData () {
      if (this.$refs.starTable.tableData && this.$refs.starTable.tableData.length === this.list.length) {
        this.list = this.$refs.starTable.tableData
      }
    },
    updateDatabase () {
      this.syncTableData()
      star.clear().then(res => {
        var id = this.list.length
        this.list.forEach(ele => {
          ele.id = id
          id -= 1
        })
        star.bulkAdd(this.list)
      })
    },
    rowDrop () {
      const tbody = document.getElementById('star-table').querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        onEnd ({ newIndex, oldIndex }) {
          const currRow = _this.list.splice(oldIndex, 1)[0]
          _this.list.splice(newIndex, 0, currRow)
          _this.updateDatabase()
        }
      })
    },
    getViewMode () {
      setting.find().then(res => {
        this.viewMode = res.starViewMode
      })
    },
    updateViewMode () {
      setting.find().then(res => {
        res.starViewMode = this.viewMode
        setting.update(res)
      })
    }
  },
  created () {
    this.getFavorites()
    this.getViewMode()
  },
  mounted () {
    this.rowDrop()
    window.addEventListener('resize', () => {
      if (this.$refs.starWaterfall && this.view === 'Star') {
        this.$refs.starWaterfall.resize()
        this.$refs.starWaterfall.refresh()
        setTimeout(() => {
          this.$refs.starWaterfall.refresh()
        }, 500)
      }
    }, false)
  }
}
</script>
