<template>
  <div style="text-align: left">
    <div class="table-search" v-if="searchItems.length > 0">
      <a-form class="ant-advanced-search-form" :form="form" @submit="handleSearch" layout="inline"
              @change="handleSearchFormChange">
        <a-form-item v-for="menuItem in searchItems" :key="menuItem.key" :label="menuItem.label">
          <a-input
            v-decorator="[menuItem.key]"
            :placeholder="menuItem.placeholder || ''"
            v-if="menuItem.type === 'input'"
          />
          <a-select
            v-decorator="[menuItem.key]"
            :placeholder="menuItem.placeholder || ''"
            v-else-if="menuItem.type === 'select'"
          >
            <a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
              {{ cItem.label }}
            </a-select-option>
          </a-select>
          <a-range-picker
            :placeholder="menuItem.placeholder || ''" v-decorator="[menuItem.key]"
            v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD"/>
        </a-form-item>
        <a-form-item>
          <a-button type="primary" html-type="submit" v-if="!hideSearch">查询</a-button>
          <a-button :style="{ marginLeft: '8px' }" @click="reset" v-if="!hideSearch">重置</a-button>
          <slot name="search-button" v-bind:search="form.getFieldsValue()"></slot>
        </a-form-item>
      </a-form>
    </div>
    <a-divider v-if="!hideButton && searchItems.length > 0"/>
    <div class="table-operations" v-if="!hideButton">
      <a-button @click="addRow" type="primary">
        添加
      </a-button>
    </div>
    <a-table v-bind="tableProps" :pagination="page" :row-key="primaryKey" :columns="realColumns"
             :data-source="tableDataSource" @change="handleChange">
      <span slot="action" slot-scope="text, record">
        <a-button type="danger" size="small" @click="deleteRow(record)">删除</a-button>
        <a-divider type="vertical"/>
        <a-button type="primary" size="small" @click="editRow(record)">编辑</a-button>
      </span>
      <span slot="details" slot-scope="text, record">
<!--        <a-button type="danger" size="small" @click="deleteRow(record)">删除</a-button>-->
        <!--        <a-divider type="vertical"/>-->
        <a-button type="primary" size="small" @click="viewDetails(record)">详情</a-button>
      </span>
    </a-table>
    <a-modal
      :title="dialog.title"
      :visible="dialog.visible"
      :confirm-loading="dialog.loading"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <a-form class="ant-advanced-search-form" :form="editForm" @submit="handleSearch" @change="handleSearchFormChange">
        <a-form-item v-for="menuItem in formItems" :key="menuItem.key" :label="menuItem.label" v-if="!menuItem.hide">
          <a-input
            v-bind="menuItem.props || {}"
            v-decorator="gtDecorator(menuItem)"
            :placeholder="menuItem.placeholder || ''"
            v-if="menuItem.type === 'input'"
          />
          <a-select
            v-decorator="gtDecorator(menuItem)"
            :placeholder="menuItem.placeholder || ''"
            v-else-if="menuItem.type === 'select'"
            v-bind="menuItem.props || {}"
          >
            <a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
              {{ cItem.label }}
            </a-select-option>
          </a-select>
          <a-tree-select
            v-bind="menuItem.props || {}"
            v-decorator="gtDecorator(menuItem)"
            :placeholder="menuItem.placeholder || ''"
            allow-clear
            :tree-data="menuItem.children"
            tree-default-expand-all
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            v-else-if="menuItem.type === 'treeSelect'"
          >
            <a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">
              {{ cItem.label }}
            </a-select-option>
          </a-tree-select>
          <a-range-picker v-bind="menuItem.props || {}" v-decorator="gtDecorator(menuItem)"
                          v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD"/>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>
<script>
export default {
  name: "user",
  data() {
    return {
      isValidate: false,
      tableDataSource: [],
      form: this.$form.createForm(this, {name: `form_${new Date().valueOf()}`}),
      editForm: this.$form.createForm(this, {name: `edit_form_${new Date().valueOf()}`}),
      dialog: {
        title: '',
        visible: false,
        isEdit: '',
        loading: false
      },
      selectRow: null,
      page: {
        pageSize: 10,
        current: 1,
        total: 0
      },
      searchFormModel: {}
    }
  },
  props: {
    tableProps: {
      type: Object,
      default: () => ({})
    },
    hideSearch: {
      type: Boolean,
      default: false
    },
    hideAction: {
      type: Boolean,
      default: false
    },
    hideButton: {
      type: Boolean,
      default: false
    },
    // 表单内容配置
    formItems: {
      type: Array,
      default: () => []
    },
    // 列表列配置
    columns: {
      type: Array,
      default: () => []
    },
    primaryKey: {
      type: String,
      default: 'id'
    },

    apiConf: {
      type: Object,
      default: () => ({})
    },
  },
  computed: {
    searchItems() {
      return this.formItems.filter(item => !!item.isSearch)
    },
    realColumns() {
      if (this.hideAction) return [...this.columns]
      return [
        ...this.columns,
        {
          title: '操作',
          dataIndex: 'action',
          scopedSlots: {customRender: 'action'},
          fixed: 'right',
          width: 155
        },
      ]
    }
  },
  watch: {},
  mounted() {
    this.handleSearch()
  },
  methods: {
    viewDetails(data){
      this.$emit('viewDetails',data)
    },
    gtDecorator(menuItem) {
      if (menuItem.rules) {
        this.isValidate = true
        return [
          menuItem.key,
          {rules: menuItem.rules}
        ]
      }
      return [
        menuItem.key
      ]
    },
    handleSearchFormChange(changedFields) {
      this.searchFormModel = {...this.searchFormModel, ...changedFields}
    },
    addRow() {
      this.handleCancel()
      this.$emit('edit', false)
      this.dialog.visible = true
    },
    async editRow(row) {
      if (this.apiConf.detailApi) {
        const {api, method, detailHandler} = this.apiConf.detailApi
        const {data} = await this[`$${method}`](api, {[this.primaryKey]: row[this.primaryKey]})
        this.selectRow = detailHandler && detailHandler(data) || data
      } else {
        this.selectRow = row
      }
      this.dialog.title = '编辑'
      this.dialog.visible = true
      this.dialog.isEdit = true
      this.dialog.loading = false
      this.$emit('edit', true)
      setTimeout(() => {
        this.editForm.setFieldsValue(this.selectRow)
      }, 200)
    },
    deleteRow(row) {
      const self = this
      if (!self.apiConf.deleteApi) return
      this.$confirm({
        title: '确认要删除么?',
        okText: '确认',
        okType: 'danger',
        cancelText: '再想想',
        onOk() {

          const {api, deleteKey, paramsType, method} = self.apiConf.deleteApi
          let params = {}
          if (paramsType === 'Array') {
            params = [row[self.primaryKey]]
          } else {
            params[deleteKey] = row[self.primaryKey]
          }
          self[`$${method}`](api, params, {params: params}).then(res => {
            self.handleSearch()
          })
        }
      });


    },
    handleChange({pageSize, current}) {
      this.page.pageSize = pageSize
      this.page.current = current
      this.handleSearch()
    },
    reset() {
      this.form.resetFields();
    },
    async handleSearch(e) {
      e && e.preventDefault();
      const values = this.form.getFieldsValue()
      const {api, noPage, method} = this.apiConf.listApi
      const {data} = await this[`$${method}`](api, {
        ...values,
        pageSize: this.page.pageSize,
        current: this.page.current,
      })
      if (noPage) {
        this.page = false
        this.tableDataSource = data
      } else {
        this.page.total = data.total || 0
        this.tableDataSource = data.items
      }
    },
    async handleOk() {
      if (this.isValidate) {
        this.editForm.validateFields(async (err, values) => {
          if (!err) {
            if (this.dialog.isEdit) {
              const {api, method, updateKey} = this.apiConf.editApi
              await this[`$${method}`](api, {
                [updateKey || this.primaryKey]: this.selectRow[this.primaryKey],
                ...values
              })
            } else {
              const {api, method} = this.apiConf.addApi
              await this[`$${method}`](api, values)
            }
            this.handleCancel()
            this.handleSearch()
          }
        });
      } else {
        const values = this.editForm.getFieldsValue()
        if (this.dialog.isEdit) {
          const {api, method, updateKey} = this.apiConf.editApi
          await this[`$${method}`](api, {
            [updateKey || this.primaryKey]: this.selectRow[this.primaryKey],
            ...values
          })
        } else {
          const {api, method} = this.apiConf.addApi
          await this[`$${method}`](api, values)
        }
        this.handleCancel()
        this.handleSearch()
      }

    },
    handleCancel() {
      this.selectRow = null
      this.dialog.title = '添加'
      this.dialog.visible = false
      this.dialog.isEdit = false
      this.dialog.loading = false
      this.editForm.resetFields()
    },
  }
}
</script>
<style scoped lang="less">
.table-operations {
  margin-bottom: 16px;
}

.ant-form-item {
  margin-bottom: 0;
}

.ant-divider-horizontal {
  margin: 16px 0;
}

.table-operations > button {
  margin-right: 8px;
}
</style>
