/* global SineWaves */
import _ from 'lodash'
import Vue from 'vue'
import axios from 'axios'
import ELEMENT from 'element-ui'
import config from './config/index.js'
import util from './common/util.js'
_.merge(axios.defaults, config.axios)

Vue.use(ELEMENT)

window.app = new Vue({
  el: '#app',
  data () {
    var checkJNDI = (rule, value, callback) => {
      if (this.step1FormData.isJNDIPool && value.trim().length === 0) {
        return callback(new Error('不能为空'))
      } else {
        callback()
      }
    }
    var checkJDBCURL = (rule, value, callback) => {
      if (this.step1FormData.isJDBCURL && value.trim().length === 0) {
        return callback(new Error('不能为空'))
      } else {
        callback()
      }
    }
    var checkAddressAndPort = (rule, value, callback) => {
      if (!this.step1FormData.isJDBCURL && this.step1FormData.serverType !== 'DerbyEmbedded' && value.trim().length === 0) {
        return callback(new Error('不能为空'))
      } else {
        callback()
      }
    }
    var notNull = (rule, value, callback) => {
      if (!value || value.trim().length === 0) {
        return callback(new Error('不能为空'))
      } else {
        callback()
      }
    }
    return {
      step1FormData: {
        serverType: 'MYSQL',
        importData: true,
        JDBCURL: '',
        JNDIName: 'jdbc/zcms',
        autoCreate: true,
        isJNDIPool: false,
        isJDBCURL: false,
        isLatin1Charset: false
      },
      step2FormData: {
        address: '',
        port: '3306',
        DBName: '',
        userName: '',
        password: ''
      },
      step1FormRules: {
        serverType: [{
          required: true,
          validator: notNull,
          trigger: 'blur,change'
        }],
        JNDIName: [{
          required: true,
          validator: checkJNDI,
          trigger: 'blur,change'
        }],
        JDBCURL: [{
          required: true,
          validator: checkJDBCURL,
          trigger: 'blur,change'
        }]
      },
      step2FormRules: {
        address: [{
          required: true,
          validator: checkAddressAndPort,
          trigger: 'blur,change'
        }],
        port: [{
          required: true,
          validator: checkAddressAndPort,
          trigger: 'blur,change'
        }],
        DBName: [{
          required: true,
          validator: checkAddressAndPort,
          trigger: 'blur,change'
        }],
        userName: [{
          required: true,
          validator: notNull,
          trigger: 'blur,change'
        }],
        password: [{
          required: true,
          validator: notNull,
          trigger: 'blur,change'
        }]
      },
      containShow: true,
      serverTypes: [],
      step1show: true,
      step2show: false,
      step3show: false,
      step4show: false,
      activeMenu: 'step1',
      step3Title: '正在进行初始化！',
      progressTxt: '正在初始化ZCArticle',
      installBtn: '开始初始化',
      cancelBtn: '取消安装',
      taskID: 0, // 任务ID
      progressPercent: 0, // 进度百分比
      stopTask: false // 是否已经停止任务
    }
  },
  methods: {
    downloadSQL (type) {
      window.location.href = `./ui/install/sql?type=` + type
    },
    onServerTypeChange (val) {
      if (val === 'ORACLE') {
        this.step2FormData.port = '1521'
      } else if (val === 'DB2') {
        this.step2FormData.port = '50000'
      } else if (val.startsWith('MSSQL')) {
        this.step2FormData.port = '1433'
      } else if (val === 'MYSQL') {
        this.step2FormData.port = '3306'
      } else if (val === 'SYBASE') {
        this.step2FormData.port = '5000'
      } else if (val === 'DM') {
        this.step2FormData.port = '5326'
      }
    },
    onJNDIPoolClick (val) {
      if (val) {
        if (this.step1FormData.isJDBCURL === true) {
          this.step1FormData.isJDBCURL = false
        }
      }
    },
    onJDBCURLClick (val) {
      if (val) {
        if (this.step1FormData.isJNDIPool === true) {
          this.step1FormData.isJNDIPool = false
        }
      }
    },
    async nextStep () {
      try {
        await util.validateForm(this.$refs.step1Form)
      } catch (e) {
        util.showErrorMessageBox(e)
        return
      }
      this.step1show = false
      this.step2show = true
      this.activeMenu = 'step2'
      this.installBtn = '开始初始化'
    },
    lastStep () {
      this.step1show = true
      this.step2show = false
      this.activeMenu = 'step1'
    },
    // 数据库初始化
    async install (step1) {
      try {
        step1 ? await util.validateForm(this.$refs.step1Form) : await util.validateForm(this.$refs.step2Form)
      } catch (e) {
        util.showErrorMessageBox(e)
        return
      }
      this.installBtn = '请稍等......'
      let res = {}
      try {
        res = await axios.post('/ui/install/execute', Object.assign(this.step1FormData, this.step2FormData))
      } catch (error) {
        this.installBtn = '开始初始化'
        util.showErrorMessageBox('请求超时！请重试')
        return
      }
      if (res.data.status !== 1) {
        this.installBtn = '开始初始化'
        util.showErrorMessageBox(res.data.message, true)
        return
      }
      this.step1show = false
      this.step2show = false
      this.step3show = true
      this.progressPercent = 0
      this.step3Title = '正在进行初始化！'
      this.progressTxt = '正在初始化ZCArticle'
      this.cancelBtn = '取消安装'
      this.taskID = res.data.taskID
      this.stopTask = false
      if (this.taskID) {
        let interval = setInterval(async () => {
          let progress = await axios.get(`/ui/framework/longtimetasks/${this.taskID}`)
          if (this.stopTask) {
            clearInterval(interval)
          }
          if (progress.data.data.errorFlag) {
            clearInterval(interval)
            let info = `总计${progress.data.data.errors.length}个错误:<br>`
            _.forEach(progress.data.data.errors, function(name, index){
              info += (index + 1) + name + '<br>'
            })
            util.showErrorMessageBox(info, true)
          } else if (progress.data.data.completeFlag) {
            this.progressPercent = 100
            this.activeMenu = 'step3'
            this.step3show = false
            this.step4show = true
            clearInterval(interval)
          } else {
            this.progressPercent = progress.data.data.percent
            this.progressTxt = progress.data.data.currentInfo || this.progressTxt
          }
        }, 1000)
      } else {
        this.activeMenu = 'step3'
        this.step3show = false
        this.step4show = true
      }
    },
    async stopInstall () {
      if (this.cancelBtn === '任务己取消') {
        return
      }
      this.step3Title = '正在取消应用安装操作，请稍后---'
      this.cancelBtn = '正在取消任务...'
      this.stopTask = true
      let interval = setInterval(async () => {
        let res = await axios.put('/ui/framework/longtimetasks/stoped', {
          taskID: this.taskID
        })
        if (res.data.status === 1) {
          this.cancelBtn = '任务己取消'
          clearInterval(interval)
        }
      }, 1000)
    },
    onLatin1CharsetClick (val) {
      if (val) {
        this.isLatin1Charset = true
      } else {
        this.isLatin1Charset = false
      }
    }
  },
  async created () {
    let res = await axios.get('/ui/install/init')
    if (res.data.data.lowMemory) {
      this.$alert('特别提示：当前JVM最大内存数较小，建议调整-Xmx参数到256M以上,以避免出现运行一段时间后内存溢出并停止响应的状况', '提示', {
        type: 'warning'
      })
    }
    if (res.data.data.notInstall) {
      this.containShow = true
    } else {
      this.containShow = false
      window.setTimeout(function () {
        window.location = 'index.html'
      }, 3000)
    }

    let dbTypesRes = await axios.get('/ui/dbtype')
    if (dbTypesRes.data.status === 1) {
      this.serverTypes = dbTypesRes.data.data
    } else {
      util.showErrorMessageBox('数据库类型获取失败！请刷新当前页面')
    }
  },
  mounted () {
    // 绘制底部波浪效果
    var canvasEl = document.getElementById('bgWave')
    // 不支持Canvas的情况下设置背景图片做向下兼容
    if (typeof canvasEl.getContext === 'undefined') {
      this.$refs.bgWave.class = 'bgWave-img'
    }
    /* eslint-disable no-new */
    new SineWaves({
      el: canvasEl,
      speed: 5,
      width: function () {
        return 1676
      },
      height: function () {
        return 375
      },
      wavesWidth: '130%',
      ease: 'SineInOut',
      waves: [{
        timeModifier: 0.5,
        lineWidth: 0,
        amplitude: 150,
        wavelength: 200,
        segmentLength: 1,
        fillColor: 'rgba(185, 243, 214, 0.6)',
        strokeStyle: 'rgba(185, 243, 214, 0.6)',
        type: 'Fibonacci'
      },
      {
        timeModifier: 1,
        lineWidth: 0,
        amplitude: -75,
        wavelength: 100,
        segmentLength: 1,
        fillColor: 'rgba(185, 243, 214, 0.6)',
        strokeStyle: 'rgba(185, 243, 214, 0.6)',
        type: 'Fibonacci'
      },
      {
        timeModifier: 0.8,
        timeDelay: 1,
        lineWidth: 2,
        amplitude: 100,
        wavelength: 150,
        segmentLength: 1,
        fillColor: 'rgba(185, 243, 214, 0.6)',
        type: 'Fibonacci'
      }],
      initialize: function () {},

      resizeEvent: function () {
        var gradient = this.ctx.createLinearGradient(0, 0, this.width, 0)
        gradient.addColorStop(0, 'rgba(0, 0, 0, 0)')
        gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)')
        gradient.addColorStop(1, 'rgba(0, 0, 0, 0)')

        var index = -1
        var length = this.waves.length
        while (++index < length) {
          this.waves[index].strokeStyle = gradient
        }

        // Clean Up
        index = void 0
        length = void 0
        gradient = void 0
      }
    })
  }
})
