<template>
  <div class="tableComStyle">
    <div class="searchFormStyle qg-table">
      <Form @submit.native.prevent inline ref="searchForm" :rules="searchCondition.rules || {}" :model="searchForm" class="inline">
        <FormItem :key="getKey(item.key)" :prop="getKey(item.key)" :rules="item.rules" :label="item.label" v-for="item in searchCondition">
          <Input v-model="searchForm[item.key]" placeholder="" class="comWidth" v-if="item.type === 'input'" clearable />
          <Select ref="searchSelect" v-model="searchForm[item.key]" class="comWidth" filterable v-else-if="item.type === 'select'" clearable>
            <Option :value="isNum(value, item.number)" :key="value" v-for="(label,value) in item.option" :label="label" />
          </Select>
          <DatePicker v-else-if="item.type === 'date'" class="timeWidth" type="datetimerange" placeholder="" v-model="searchForm[item.key]"></DatePicker>
          <treeselect v-else-if="item.type === 'treeSelect'" v-model.number="searchForm[item.key]" :multiple="false" :options="item.option" placeholder="请选择" :normalizer="normalizer" style="width: 180px;" />
        </FormItem>
        <FormItem class="btnGroupStyle">
          <div>
            <Button class="btnStyle" @click="reset()">重置</Button>
            <Button type="primary" class="btnStyle" @click="query()">查询</Button>
          </div>
        </FormItem>
      </Form>
    </div>
    <div class="tableGroupStyle">
      <div v-if="!hideAdd" class="toolBarStyle">
        <h3>查询数据</h3>
        <div>
          <Button type="primary" class="btnStyle" @click="newEvent()">新增</Button>
          <slot></slot>
        </div>
      </div>
      <Tabs class="table-tabs" v-if="showSelected" :value="selectedTab">
        <TabPane name="1" :label="`全部${title}`">
          <Table
            :height="height"
            @on-select-cancel="selectionCancel"
            @on-selection-change="selectionChange"
            :columns="renderColumns"
            :data="tableData"
            class="tableStyle"
          />
          <Page
            :total="total"
            v-if="total > 0"
            show-elevator
            show-sizer
            class="pageStyle"
            :current="searchForm.pageNo"
            :pageSize="searchForm.pageSize"
            @on-change="changePageNo"
            @on-page-size-change="changePageSize"
          />
        </TabPane>
        <TabPane name="2" :label="`已选${title}`">
          <Table
            :height="height"
            @on-select-cancel="selectionCancel"
            @on-selection-change="selectionChange"
            :columns="renderColumns"
            :data="tableData"
            class="tableStyle"
          />
        </TabPane>
      </Tabs>
      <template v-else>
          <Table
            :height="height"
            @on-select-cancel="selectionCancel"
            @on-selection-change="selectionChange"
            :columns="renderColumns"
            :data="tableData"
            class="tableStyle"
          />
          <Page
            :total="total"
            v-if="total > 0"
            show-elevator
            show-sizer
            class="pageStyle"
            :current="searchForm.pageNo"
            :pageSize="searchForm.pageSize"
            @on-change="changePageNo"
            @on-page-size-change="changePageSize"
          />
      </template>
    </div>
  </div>
</template>
<script>
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import { cloneDeep } from 'lodash';

export default {
  components: { Treeselect },
  props: {
    columns: {
      type: Array,
      default: () => ([])
    },
    title: String,
    hideAdd: Boolean,
    // showSelected: false, // todo
    request: Function,
    toolBar: Function,
    height: Number,
  },
  data() {
    return {
      cols: this.transformData(),
      tableData: [],
      total: 0,
      searchForm: {
        pageSize: 10,
        pageNo: 1,
      },
      showSelected: false, // todo
      searchCondition: [],
      selectedTab: '1'
    };
  },
  watch: {
    searchCondition: {
      handler: function(newVal = []) {
        newVal.forEach(item => {
          this.$set(this.searchForm, item.key, item.value || null)
        });
      },
      immediate: true,
    }
  },
  computed: {
     renderColumns: function() {
       return this.handleColumns(this.cols)
     }
  },
  methods: {
    changePageNo(page) {
      this.query(page);
      this.$emit('on-page-change', page);
    },
    changePageSize(size) {
      this.searchForm.pageSize = size;
      this.query();
    },
    async query(page = 1) {
      this.$refs.searchForm.validate(async val => {
        if (val) {
          this.searchForm.pageNo = page;
          this.selectedTab = '1';
          const getQueryData = (await this.request(this.searchForm)) || {};
          this.tableData = getQueryData.data || [];
          this.total = getQueryData.total || 0;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
      // 处理select bug
      this.$refs.searchSelect.forEach(selectEle => {
        selectEle.setQuery(null);
      });
    },
    isArray(key) {
      return Array.isArray(key);
    },
    getKey(key) {
      return (this.isArray(key) && key[0]) || key;
    },
    reset() {
      this.resetForm('searchForm');
      this.searchForm.pageSize = 10;
      this.searchForm.pageNo = 1;
    },
    refresh() {
      this.query();
    },
    newEvent(e) {
      this.$emit('newBtnClick', e);
    },
    handleColumns(col=[]) {
      const data = []
      this.searchCondition = [];
      col.forEach(item => {
        item.align = item.align || 'center';
        if (item.valueEnum&&!item.render) {
          item.render = (h, params) => {
            return h('div', item.valueEnum[params.row[item.key]])
          }
        }
        if (!item.hideSearch && item.key !== 'action' && !item.type){
          this.searchCondition.push({label: item.title, type: item.formType, rules: item.rules, value: item.value, option: item.valueEnum, key: item.key, number: item.number})
        }
        if (!item.hideTable) {
          data.push(item)
        }
      })
      return data
    },
    isNum(value, number) {
       return number ? +value : value;
    },
    selectionChange(selection) {
      this.$emit('on-selection-change', selection);
    },
    selectionCancel(selection, row) {
      this.$emit('on-select-cancel', selection, row);
    },
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children;
      }
      return {
        id: node.id || null,
        label: node.label,
        children: node.children,
      };
    },
    transformData() {
      return cloneDeep(this.columns).map(item => {
        // 处理valueEnum为异步函数的情况
        if (item.valueEnum && typeof item.valueEnum === 'function') {
          item.valueEnum().then(v => {
            this.cols.forEach(column => {
              if (column.key === item.key) {
                column.valueEnum = v;
              }
            })
          });
          item.valueEnum = [];
        }
        return item;
      })
    }
  },
  mounted() {
    this.$nextTick(this.query);
  },
};
</script>
<style scoped lang="less">
// @import '../../styles/comment.less';
@padding: 25px;

.tableComStyle {
  height: 100%;
  background: #f5f5f5;
  padding: 15px;
  // min-height: 1000px;
  .searchFormStyle {
    text-align: left;
    clear: both;
    background-color: #fff;
    padding: @padding;
    min-height: 70px;
    font-size: 0;

    .labelStyle {
      font-weight: bold !important;
      display: inline-block;
    }

    /deep/ .ivu-form {
      margin-bottom: -24px;
    }

    .required::before {
      content: '* ';
      color: #ed3f14;
    }
  }

  .btnStyle {
    margin-right: 10px;
  }

  .tableStyle {
    margin-top: 15px;
  }

  .comWidth {
    width: 200px;
  }

  .timeWidth {
    width: 320px;
  }

  .btnGroupStyle {
    text-align: left;
    float: right;
  }

  .inline {
    display: inline-block;
  }

  .tableGroupStyle {
    background: #fff;
    padding: @padding;
    margin-top: 15px;

    .toolBarStyle {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .pageStyle {
      margin-top: 20px;
      width: 100%;
      text-align: right;
    }
  }
}
</style>
<style lang="less">
.qg-table {
  .ivu-form-item-label {
    font-weight: bold;
    display: inline-block;
  }

  .ivu-form-item-content {
    display: inline-block;
  }
}

.table-tabs {
  width: 1030px;
}
</style>
