<template>
  <div>
    <filter-container v-if="!hideFilter" :inputs="filterFields" :has-export="hasExport" @all="filterAllHandler">
      <slot name="filter-handlers" />
    </filter-container>
    <my-table ref="my-table" :fields="tableFields" :list="list" :loading="listLoading" :show-selection="showSelection" @row-click="(e) => {$emit('row-click', e)}">
      <template v-for="(item) of tableFields" :slot="item.prop" slot-scope="scope">
        <slot v-bind="scope" :name="item.prop" />
      </template>
    </my-table>
    <pagination
      v-if="!hidePagination && total>0"
      :total="total"
      :page.sync="query.current"
      :limit.sync="query.size"
      class="no-print"
      @pagination="getList"
    />
  </div>
</template>

<script>
import FilterContainer from './FilterContainer'
import MyTable from '../coreCmp/MyTable.vue'
import Pagination from './Pagination'
import config from '../config'

import { exportExcel, objEmitFieldManager, fieldsManager } from '../utils'

import _ from 'lodash'

export default {
  provide() {
    return {
      getList: this.getList
    }
  },
  components: { FilterContainer, MyTable, Pagination },
  props: {
    listQuery: {
      type: Object,
      default: () => ({})
    },
    listMethod: {
      type: Function,
      default: () => Promise.resolve({ lists: [], total: 0 })
    },
    filterFields: {
      type: Array,
      default: () => []
    },
    tableFields: {
      type: [Array, Object],
      default: () => []
    },
    exportName: {
      type: String,
      default: ''
    },
    exportFields: {
      type: [Array, Object],
      default: () => []
    },
    listKey: {
      type: String,
      default: 'd.records'
    },
    listTotalKey: {
      type: String,
      default: 'd.total'
    },
    listManager: {
      type: Function,
      default: (data) => data
    },
    searchManager: {
      type: Function,
      default: (data) => data
    },
    hideFilter: {
      type: Boolean,
      default: false
    },
    hidePagination: {
      type: Boolean,
      default: false
    },
    hasExport: {
      type: Boolean,
      default: false
    },
    showSelection: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      listLoading: false,
      list: [],
      total: 0,
      query: {
        ...config.tablePage.listQuery,
        ...this.listQuery
      }
    }
  },
  watch: {
    listQuery: {
      deep: true,
      handler() {
        this.query = {
          ...this.query,
          ...config.tablePage.listQuery,
          ...this.listQuery
        }
      }
    },
    query() {
      this.getList()
    }
  },
  created() {
    this.getList()
  },
  methods: {
    async getList() {
      this.listLoading = true
      try {
        const { res, list } = await this.requestList(this.query)
        this.list = list
        this.total = _.result(res, this.listTotalKey, 0)
        this.$emit('load', res)
        this.listLoading = false
      } catch (err) {
        console.log(err)
        this.listLoading = false
      }
    },
    async requestList(query) {
      const res = await this.listMethod(this.searchManager(query))
      const list = this.listManager(_.result(res, this.listKey, []))
      // console.log(list)
      // const total = _.result(res, this.listTotalKey, 0)
      return {
        res,
        list,
        // total
      }
    },
    filterAllHandler(e) {
      const { type, detail } = e
      // console.log(this.query, detail)
      // console.log(e)
      const query = objEmitFieldManager({ ...this.query, ...detail })
      switch (type) {
        case 'search':
        case 'reset':
        case 'export':
          this.$set(this, 'query', query)
          this.$emit('search', this.query)
      }
      if (type === 'export') {
        this.handleDownload()
      }
    },
    async handleDownload() {
      this.downloadLoading = true
      try {
        const fields = fieldsManager(this.tableFields).filter(item => item.prop !== 'operation')
        const { list } = await this.requestList({ ...this.query, ...config.exportQuery || {}})
        await exportExcel(fields, list, { filename: this.exportName })
        this.downloadLoading = false
      } catch (err) {
        this.downloadLoading = false
      }
    },
    getSelection(...args) {
      return this.$refs['my-table'].getSelection(...args)
    }
  }
}
</script>
