<template>
  <el-dropdown class="download-header float-left mr-3" ref="downloadmenu" trigger="click" :hide-on-click=false>
    <span class="el-dropdown-link">
      <span class="badge badge-orange">
        <i class="fas fa-download"></i><span v-show="downloadNum !== 0"> {{ downloadNum }}</span>
      </span>
    </span>
    <!--<el-button @click="testbtn">test</el-button>-->
    <el-dropdown-menu slot="dropdown" class="downloadlist">
      <div v-for="(item, index) in downloads" v-show="!item.delete" :key="item.id" class="downloaditem">
        <div class="pb-2"><span class="float-right">{{ item.size }}</span>{{ item.fulltitle }}</div>
        <div class="pb-2">
          <div class="progress-content" v-if="item.isfinish === false">
            <div class="float-right">
              <span v-if="item.show">
                <i v-show="item.pause" class="far fa-pause-circle text-secondary mr-2" @click="operationDownload('pause', item.id, index)"></i>
                <i v-show="item.resume" class="far fa-play-circle text-secondary mr-2" @click="operationDownload('resume', item.id, index)"></i>
                <i v-show="item.start" class="far fa-play-circle text-secondary mr-2" @click="operationDownload('start', item.id, index)"></i>
              </span>
              <i class="fas fa-times text-danger" @click="deleteDownload(item.id, index)"></i>
            </div>
            <div class="progress-width">
              <el-progress :text-inside="true" :stroke-width="18" :percentage="item.percent" status="success"></el-progress>
            </div>
          </div>
          <div class="progress-content" v-else>
            <div class="float-right"><i class="fas fa-times text-danger" @click="deleteDownload(item.id, index)"></i></div>
            <div class="progress-width">
              <button v-if="item.status === 2" @click="installbtn(item.id, index)" class="btn btn-blue btn-sm btn-lg btn-block">安装软件</button>
              <button v-else-if="item.status === 3" class="btn btn-secondary btn-sm btn-lg btn-block">正在安装本软件...</button>
              <button v-else-if="item.status === 4" class="btn btn-success btn-sm btn-lg btn-block">已安装</button>
            </div>
          </div>
        </div>
      </div>
    </el-dropdown-menu>
  </el-dropdown>
</template>

<script>
  import mixin from '../mixin'
  const fs = require('fs-extra')
  const path = require('path')
  const lodashId = require('lodash-id')
  const ffi = require('ffi')
  export default {
    mixins: [mixin],
    data () {
      return {
        downloadNum: 0,
        downloads: ''
      }
    },
    created () {
      this.$electron.ipcRenderer.on('downloadtips', (event, msg) => {
        let percent = msg.percent
        let info = this.$db.read().get('sc_download').getById(msg.id).value()
        info.percent = percent
        console.log(info)
        this.downloads.splice(msg.index, 1, info)
        if (!this.checkOnline() && info.pause === true) {
          this.operationDownload('pause', msg.id, msg.index)
        }
      })
      this.$db._.mixin(lodashId)
      this.downloads = this.$db.read().get('sc_download').value()
      this.downloadNum = this.$db.read().get('sc_download').filter({delete: false}).size().value()

      this.$electron.ipcRenderer.on('downloadsuccess', (event, msg) => {
        let info = this.$db.read().get('sc_download').getById(msg.id).value()
        info.isfinish = true
        info.show = false
        info.pause = false
        info.savepath = msg.savepath
        info.status = 2
        this.$db.read().get('sc_download').getById(msg.id).assign(info).write()
        // 通知下载完成
        let notification = {
          title: '启动器',
          body: info.fulltitle + '下载完成'
        }
        let myNotification = new window.Notification(notification.title, notification)
        this.downloads.splice(msg.index, 1, info)
        // 下载完成当前后 获取下一个info并启动它，没有则停止
        let info2 = this.$db.read().get('sc_download').find({ status: 1 }).value()
        if (info2 !== undefined) {
          info2.show = true
          info2.status = 5
          this.$db.read().get('sc_download').getById(info2.id).assign(info2).write()
          let index = this.downloads.findIndex(function (item) {
            return item.id === info2.id
          })
          this.downloads.splice(index, 1, info2)
          this.operationDownload('start', info2.id, index)
        }
        myNotification.onclick = () => {
          return true
        }
      })

      this.$electron.ipcRenderer.on('InstallResult', (event, item) => {
        let info = this.$db.read().get('sc_download').getById(item.id).value()
        if (item.status === 400) {
          this.$message.error(item.msg)
          this.$db.read().get('sc_download').updateById(item.id, { status: 2 }).write()
          info.status = 2
          this.downloads.splice(item.index, 1, info)
        } else {
          this.$db.read().get('sc_download').updateById(item.id, { status: 4 }).write()
          info.status = 4
          this.downloads.splice(item.index, 1, info)
        }
      })
    },
    beforeDestroy () {
    },
    methods: {
      checkOnline () {
        if (!navigator.onLine) {
          this.$message.error('当前网络不可用,无法下载')
          return false
        } else {
          return true
        }
      },
      operationDownload (status, id, index) {
        let info = this.$db.read().get('sc_download').getById(id).value()
        if (this.checkOnline()) {
          if (status === 'start') {
            this.$electron.ipcRenderer.send('download', {id: id, index: index})
            info.start = false
            info.resume = false
            info.pause = true
          } else if (status === 'resume') {
            this.$electron.ipcRenderer.send(status, id)
            info.pause = true
            info.resume = false
            info.start = false
          }
        }
        if (status === 'pause') {
          this.$electron.ipcRenderer.send(status, id)
          info.pause = false
          info.resume = true
          info.start = false
        }
        this.downloads.splice(index, 1, info)
        this.$db.read().get('sc_download').getById(id).assign(info).write()
      },
      deleteDownload (id, index) {
        try {
          let info = this.$db.read().get('sc_download').getById(id).value()
          if (info.status === 5) {
            if (info.start === false) {
              this.$electron.ipcRenderer.send('cancel', id)
              info.show = false
              info.start = true
              info.pause = false
              info.resume = false
            }
            // 改变下一个数据的下载状态，没有则结束
            let info2 = this.$db.read().get('sc_download').find({status: 1}).value()
            if (info2 !== undefined) {
              info2.show = true
              info2.status = 5
              this.$db.read().get('sc_download').getById(info2.id).assign(info2).write()
              let index2 = this.downloads.findIndex(function (item) {
                return item.id === info2.id
              })
              this.downloads.splice(index2, 1, info2)
              // this.operationDownload('start', info2.id, index)
            }
          }
          info.delete = true
          info.status = 6
          this.$db.read().get('sc_download').getById(id).assign(info).write()
          this.downloads.splice(index, 1, info)
          // this.$db.read().get('sc_download').removeById(id).write()
          // this.downloads.splice(index, 1)
          this.downloadNum = this.$db.read().get('sc_download').filter({delete: false}).size().value()
          // fs.removeSync(info.savepath)
        } catch (err) {
          console.log(err)
        }
      },
      adddownload (downID) {
        if (this.checkOnline()) {
          this.$refs.downloadmenu.show()
          let softwarejson = path.join('data/sc_software.json')
          let downlist = fs.readJsonSync(softwarejson).sc_down
          let downinfo = downlist.find(function (item) {
            return item.down_id === downID
          })
          delete downinfo.regedits
          delete downinfo.versionDesc

          downinfo.isfinish = false
          downinfo.percent = 0
          downinfo.savepath = downinfo.down_url.substring(downinfo.down_url.lastIndexOf('/') + 1)
          downinfo.addtime = Date.parse(new Date()) / 1000
          downinfo.show = false
          downinfo.pause = false
          downinfo.resume = false
          downinfo.start = true
          downinfo.delete = false
          downinfo.status = 1
          // 若产品不存在则插入到数据库sc_productData中,并隐藏
          let productinfo = this.$db.read().get('sc_productData').find({ product_id: downinfo.product_id }).value()
          if (productinfo === undefined) {
            let productlist = fs.readJsonSync(softwarejson).sc_product
            let scproductinfo = productlist.find(function (item) {
              return item.product_id === downinfo.product_id
            })
            scproductinfo.addtime = Date.parse(new Date()) / 1000
            scproductinfo.isshow = false
            productinfo = this.$db.read().get('sc_productData').insert(scproductinfo).write()
          }
          downinfo.pid = productinfo.id
          let info = this.$db.read().get('sc_download').insert(downinfo).write()
          this.downloads.push(downinfo)
          this.downloadNum = this.$db.read().get('sc_download').filter({delete: false}).size().value()
          // 如果downloads中没有未下载的info，就让新增的info进入下载过程
          let info2 = this.$db.read().get('sc_download').find({status: 5}).value()
          let info3 = this.$db.read().get('sc_download').find({status: 1}).value()
          if (info2 === undefined && info.id === info3.id) {
            info.show = true
            info.status = 5
            this.$db.read().get('sc_download').getById(info.id).assign(info).write()
            let index = this.downloads.findIndex(function (item) {
              return item.id === info.id
            })
            this.operationDownload('start', info.id, index)
          }
        }
      },
      testbtn () {
        // console.log('C:\\Program Files (x86)\\纵横软件\\纵横结算决算计量一体化软件(云版)')
        // this.$electron.shell.openItem('C:\\Program Files (x86)\\纵横软件\\纵横结算决算计量一体化软件(云版)')
        window.open('http://softmicroindex.smartcost.com.cn/')
      },
      installbtn (id, index) {
        // 安装exe监测,5s后开始监听安装状态
        let info = this.$db.read().get('sc_download').getById(id).value()
        if (info.status === 2) {
          // 判断启动器是否已安装本软件
          let exesqlinfo = this.$db.read().get('sc_exeData').find({ regeditName: info.regedit, product_version: info.version }).value()
          if (exesqlinfo !== undefined) {
            this.$message({
              message: `启动器已存在相同版本的 ${info.fulltitle} 软件`,
              iconClass: '',
              type: 'error'
            })
          } else {
            this.$electron.shell.openItem(info.savepath)
            let self = this
            setTimeout(function () {
              info.status = 3
              self.$db.read().get('sc_download').getById(id).assign(info).write()
              self.downloads.splice(index, 1, info)
              self.watchExeInstall(index, info)
            }, 5000)
          }
        } else {
          this.$message({
            message: info.fulltitle + ' 正在安装中，请稍后......',
            iconClass: '',
            type: 'warning'
          })
        }
      },
      watchExeInstall (index, info) {
        // 监听安装程序目录,不存在则结束监听，进入判断安装是否完成or取消
        let self = this
        let interval = setInterval(function () {
          let result = self.checkExeExist(info.savepath)
          if (result === 0) {
            clearInterval(interval)
            // 判断是否完成还是取消了

            self.$electron.ipcRenderer.send('checkExeInstall', { index: index, info: info })
          }
        }, 3000)
      },
      checkExeExist (exepath) {
        try {
          let ffifile = path.join('data/fileInfo.dll')
          let libm = ffi.Library(ffifile, {
            'FindProcess': ['int', ['string']]
          })
          let exerun = libm.FindProcess(exepath)
          if (exerun === 0) {
            return 0
          }
          return 1
        } catch (err) {
          console.error('ffi.Library', err)
        }
      }
    }
  }
</script>