// 类库相关
import Vue from 'vue'
import ElementUI from 'element-ui'
import echarts from 'echarts'
import 'element-ui/lib/theme-chalk/index.css'
import './styles/index.scss'
import Store from 'store'

import App from './App.vue'

// 项目自定义
import axios from '@/https/request'
import API from '@/https/api'
import router from './router'
import store from './store'
import keys from './config/keys'
import utils from './utils'
import constants from './config/constant'
import exportExcel from './components/exportExcel/exportExcel'
import importExcel from './components/importExcel/index'

// 全局组件
import globalComponents from './components'

/* eslint-disable */
// ##兼容: IE 9 requestAnimationFrame
(function() {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
      || window[vendors[x]+'CancelRequestAnimationFrame'];
  }

  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() { callback(currTime + timeToCall); },
        timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };

  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
}());

Vue.use(ElementUI, { size: 'medium' })
Vue.config.performance = true
Vue.config.productionTip = false

Vue.prototype.$exportExcel = exportExcel
Vue.prototype.$importExcel = importExcel
Vue.prototype.$echarts = echarts
Vue.prototype.$https = axios
Vue.prototype.$API = API
Vue.prototype.$utils = utils
Vue.prototype.$keys = keys
Vue.prototype.$Store = Store
Vue.prototype.$consts = constants
Vue.use(globalComponents)

/**
 * 设置表格高度
 * @param {VueInstance} vm: vue组件实例对象(一般是this)
 * */
function setTableMaxHeight (vm) {
  // 80为底部分页栏高度 32 + table margin-bottom 20 + content padding 20 + 预留空隙值
  vm.tableMaxHeight = document.body.clientHeight - utils.getTopOfWorkWindow(vm.$refs.table.$el) - 80
}

/**
 * 设置自定义表头数据
 * @param {VueInstance} vm: vue组件实例对象(一般是this)
 * */
function setCustomTableHeads (vm) {
  store.commit('framework/changeTableColumns', vm.wholeLabels) // 表格的表头

  if (vm.storeKey) {
    store.commit('framework/changeStoreKey', vm.storeKey) // 每个页面的名字
  }
  if (vm.$Store.get(vm.storeKey)) {
    vm.storeLables = vm.$Store.get(vm.storeKey)

    store.commit('framework/changeStoreLables', vm.storeLables) // 小圆点的默认选中的表头
    // 表格的表头
    store.commit('framework/changeNewColumns', vm.storeLables)
  } else {
    vm.storeLables = []
    store.commit('framework/changeNewColumns', [])
    store.commit('framework/changeStoreLables', vm.storeLables)
  }
}
// 自定义指令
/**
 * v-auth
 * 用法: v-auth="权限代码"
 * 说明: 为所有指令元素注册权限, 与接口数据匹配, 如果无权限则直接移除元素
 * 备注: 2018.10.26 17:07 提交复杂保存逻辑, 可根据时间回溯
 * */
Vue.directive('auth', {
  // 直接使用 function (表示 bind 和 update 触发相同的操作)会在没有权限时, 报 el.parentNode 为 null 的错
  inserted: (el, binding, vnode) => {
    if (!JSON.parse(store.state.framework.btnPermission)[binding.value]) {
      el.parentNode.removeChild(el)
    }
  }
})
// 混入内容
Vue.mixin({
  computed: {
    // 上传文件成功标识
    uploadComponentSuccess () {
      return store.state.framework.uploadSuccess
    },
    newColumns () {
      return store.state.framework.newColumns
    }
  },
  watch: {
    uploadComponentSuccess () {
      this.getList && this.getList(this.query || {})
    },
    newColumns () {
      this.storeLables = this.newColumns
    }
  },
  data () {
    return {
      wholeLabels: [], // 列表完整标签
      filteredLabels: [], // 自定义过滤后的labels
      storeLables: [],
      tableMaxHeight: undefined,
    }
  },
  mounted () {
    if (this.$refs.table) {
      // 便于全屏和退出时变化表格高度
      window.addEventListener('resize', () => {
        setTableMaxHeight(this)
      })
      // 设置表格高度
      setTableMaxHeight(this)
      // 设置表头完整数据
      this.$refs.table.columns && (this.wholeLabels = this.$refs.table.columns.filter(item => item.label).map(item => item.label))
      if (this.$route.dropFilter) {
        // 设置自定义表头数据
        setCustomTableHeads(this)
      }
    }

  },
  activated () {
    if (this.$refs.table) {
      // 便于全屏和退出时变化表格高度
      window.addEventListener('resize', () => {
        setTableMaxHeight(this)
      })
      // 设置表格高度
      setTableMaxHeight(this)
      // 设置自定义表头数据
      setCustomTableHeads(this)
    }
  },
  methods: {
    // 列表格式化
    formatColumn (row, column) {
      let result = row[column.property]
      if (column.label.includes('吨')) {
        if (result) {
          result = (+result).toFixed(this.$consts.numFix.TON)
        }
      }
      return result != null ? result : '-'
    },
    // 渲染重量表头
    renderWeightHeader (h, { column, $index }) {
      (!column.width || column.width < 150) && (column.width = 150)
      return h('div', {
        class: 'rendered-weight-header',
      }, [
        h('div', null, column.label),
        h('div', null, [
          h('el-radio-group', {
            props: {
              value: column.unit || 'ton',
            },
            // 使用原生事件监听实现v-model
            nativeOn: {
              change: (e) => {
                this.$set(column, 'unit', e.target.value)
              }
            }
          }, [
            h('el-radio', {
              props: {
                label: 'ton'
              }
            }, '吨'),
            h('el-radio', {
              props: {
                label: 'KG'
              }
            }, '千克')
          ])
        ])
      ])
    },
    // 操作前确认
    operate (e, type = e.currentTarget.__vue__.command, ...otherArgs) {
      if (this.checkSelections) {
        if (this.checkSelections()) {
          this.$confirm(`是否执行 ${e.currentTarget.innerText} 操作 ?`, {
            title: `${e.currentTarget.innerText}`,
            type: 'warning',
          })
            .then(() => {
              this.operateConfirm(type, ...otherArgs)
            })
            .catch(() => {
              console.log('取消')
            })
        }
      } else {
        this.$confirm(`是否执行 ${e.currentTarget.innerText} 操作 ?`, {
          title: `${e.currentTarget.innerText}`,
          type: 'warning',
        })
          .then(() => {
            this.operateConfirm(type, ...otherArgs)
          })
          .catch(() => {
            console.log('取消')
          })
      }
    },
  },
  // 进入路由前
  beforeRouteEnter (to, from, next) {
    if (!to.meta.keepAlive) {
      // 更新排除缓存的组件, 需要组件设置 name 属性, 路由名首字母大写即为组件 name
      store.commit('framework/changeExcludeAliveComps', [utils.upperFirst(to.name)])
    }
    next(vm => {
      if (!to.meta.keepAlive) {
        // 删除在父组件中的缓存
        const index = vm.$parent.$children.findIndex(item => {
          return item.$vnode.parent && (vm._name === item._name)
        })
        index && vm.$parent.$children.splice(index, 1)
        to.meta.keepAlive = true
      }
      // 默认又进行缓存
      store.commit('framework/changeExcludeAliveComps', [])
    })
  },
})

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
