import ElTable from 'element-ui-for-gov/packages/table';
import ElTableColumn from 'element-ui-for-gov/packages/table-column';
import Pagination from 'element-ui-for-gov/packages/pagination';
import myAxios from 'axios';

const axios = myAxios.create();
/* istanbul ignore next */
export default {
  name: 'DataTable',
  props: {
    columns: {
      type: Array
    },
    data: {
      type: Array
    },
    params: {
      type: Object
    },
    requestCfg: {
      type: Object
    },
    resolveRes: {
      type: Function
    },
    resolveParams: {
      type: Function
    },
    resolveError: {
      type: Function
    },
    reqInterceptors: {
      type: Function
    },
    showPagination: {
      type: Boolean,
      default: true
    },
    paginationProps: {
      type: Object
    },
    tableProps: {
      type: Object
    },
    delay: {
      type: Boolean,
      default: false
    },
    tableOns: {
      type: Object
    },
    showLoading: {
      type: Boolean,
      default: true
    }
  },

  components: {
    ElTable,
    ElTableColumn,
    Pagination
  },

  data() {
    return {
      total: 0,
      currentPage: 1,
      currSize: this.paginationProps && this.paginationProps['page-size'] ? this.paginationProps['page-size'] : 10,
      dataList: [],
      loading: false,
      colSuffix: this.getRandom()
    };
  },

  watch: {
    'params': {
      handler() {
        this.$nextTick(this.loadData);
      },
      deep: true
    },
    data(val) {
      if (val) {
        this.total = val.length;
        this.countData();
      }
    },
    columns() {
      // columns修改则同步改变key前缀
      this.colSuffix = this.getRandom();
    }
  },

  created() {
    if (this.data) this.total = this.data.length;
    if (this.reqInterceptors) axios.interceptors.request.use(this.reqInterceptors);
    if (!this.delay) this.loadData();
    this.countData();
  },

  methods: {
    renderColumns(columnList) {
      const keys = [];
      return columnList.map((column, index) => {
        let key = (column.property || 'col' + index) + this.colSuffix;
        if (key && keys.indexOf(key) !== -1) key = key + index;
        if (key && keys.indexOf(key) === -1) keys.push(key);

        if (column.props && column.props.type === 'index') {
          // 序号
          const { currSize, currentPage } = this;
          return <ElTableColumn key={key} label={column.label} align={column.align || 'center'} scopedSlots={{
            header: () => {
              return column.props.label;
            },
            default: (s) => {
              // console.log(currSize * currentPage - currSize + s.$index + 1);
              return currSize * currentPage - currSize + s.$index + 1;
            }
          }}
          {...{props: Object.assign({'show-overflow-tooltip': true}, column.props)}}>
          </ElTableColumn>;
        }
        return <ElTableColumn prop={column.property} key={key} label={column.label} align={column.align || 'center'} scopedSlots={{
          header: column.renderHeader,
          default: column.render
        }}
        {...{props: Object.assign({'show-overflow-tooltip': true}, column.props)}}>
          {column.children && this.renderColumns(column.children)}
        </ElTableColumn>;
      });
    },
    loadData(cfg) {
      const { requestCfg, params, resolveParams, resolveRes, data, resolveError, showLoading } = this;
      if (data || !requestCfg || !requestCfg.url) return;
      if (showLoading) this.loading = true;
      let dealParams = resolveParams ? resolveParams(params) : params;
      let postData = {data: dealParams};
      if (!requestCfg.method) {
        requestCfg.method = 'post';
      } else if (requestCfg.method === 'get') {
        postData = {params: dealParams};
      }
      const config = Object.assign({ method: 'post'}, requestCfg, postData, requestCfg.method === 'post' && cfg ? { data: cfg } : { params: cfg });
      axios(config)
        .then((response) => {
          const { total, list, callback } = resolveRes(response, this);
          this.dataList = list;
          this.total = total;
          this.loading = false;
          if (callback) {
            this.$nextTick(callback);
          }
        }).catch(e => {
          resolveError && resolveError(e);
          this.loading = false;
        });
    },
    handleSizeChange(size) {
      this.currSize = size;
      this.$emit('size-change', size);
      this.countData();
    },
    handleCurrentChange(currentPage) {
      this.currentPage = currentPage;
      this.$emit('page-change', currentPage);
      this.countData();
    },
    countData() {
      if (!this.data) return;
      const { data, currentPage, currSize } = this;
      this.dataList = !this.showPagination ? data : data.slice((currentPage - 1) * currSize, currentPage * currSize);
    },
    getTableIns() {
      return this.$refs.table;
    },
    setCurrPage(num) {
      this.currentPage = num;
      this.$refs.pagination.internalCurrentPage = num;
      this.$refs.pagination.lastEmittedPage = num;
    },
    getRandom() {
      return Math.round(Math.random() * 10000) + '';
    },
    setPageSize(num) {
      this.$refs.pagination.internalPageSize = num;
    }
  },

  render() {
    const {columns, dataList, tableProps, showPagination, tableOns, loading} = this;
    return <div class="el-data-table">
      <ElTable ref="table"
        v-loading={loading}
        element-loading-text="加载中..."
        data={dataList}
        {...{on: tableOns, props: Object.assign({'tooltip-effect': 'light'}, tableProps)}}
      >
        {this.renderColumns(columns)}
      </ElTable>
      {
        showPagination &&
        <div class="el-data-table__pagination">
          <Pagination
            ref="pagination"
            layout="sizes, total, -> , prev, pager, next, jumper"
            total={this.total}
            pager-count={5}
            {...{
              props: this.paginationProps, on: {
                'size-change': this.handleSizeChange,
                'current-change': this.handleCurrentChange
              }
            }}
          />
        </div>
      }
    </div>;
  }
};
