<template>
  <div
    class="el-manager-ui"
    v-loading="loading"
    @click="stragegyFormVisbile = false"
  >
    <div
      v-if="showQuery"
      class="el-manager-ui__search_form el-manager-ui__border"
    >
      <el-form
        ref="form"
        :label-position="labelPosition"
        :model="queryModel"
        :label-width="labelWidth + 'px'"
        :rules="rules"
        :size="size"
      >
        <div class="el-manager-ui__searchBox">
          <el-row type="flex" align="middle">
            <el-col :span="8" class="el-manager-ui__searchBox--operation">
              <el-button
                v-if="showAddBtn"
                @click="$emit('create')"
                type="primary"
                icon="el-icon-plus"
              >
                创建对象
              </el-button>
            </el-col>
            <el-col :span="16" style="text-align: right; min-width: 350px;overflow: hidden;">
              <div class="el-manager-ui__searchBox--inputBox">
                <el-popover
                  popper-class="el-manager-ui__searchBox--popover"
                  placement="bottom"
                  width="500"
                  max-height="500"
                  trigger="manual"
                  v-model="stragegyFormVisbile"
                >
                  <manager-form
                    :queryItems="queryItems"
                    :queryModel="queryModel"
                    vertical
                    ref="strategyForm"
                  >
                    <template
                      :slot="slotItem.slot"
                      v-for="(slotItem, index) in querySpreadSlotItems"
                    >
                      <slot :name="slotItem.slot"></slot>
                    </template>
                  </manager-form>
                  <div slot="reference" :class="['el-manager-ui__searchBox--input',{'is-active':stragegyFormVisbile}]">
                    <div
                      class="el-manager-ui__searchBox--text"
                      v-if="selectedStrategies.length === 0"
                      @click.stop="stragegyFormVisbile = !stragegyFormVisbile"
                    >
                      请选择查询策略
                    </div>
                    <div
                      class="el-manager-ui__searchBox--inputTag"
                      @click.stop="stragegyFormVisbile = !stragegyFormVisbile"
                      v-else
                    >
                      <el-tag
                        :key="item.prop"
                        v-for="item in selectedStrategies"
                        size="medium"
                        max-width="200px"
                        closable
                        :disable-transitions="false"
                        effect="dark"
                        @close.stop="handleTagClose(item)"
                        :title="item.value"
                      >
                        {{ item.label + ':' + item.value }}
                      </el-tag>
                    </div>
                    <div
                    class="el-manager-ui__searchBox--tools"
                    :style="
                    {
                      width:!showQueryBtn?'0px':
                      selectedStrategies.length===0?'24px':
                      showStrategyConfig &&selectedStrategies.length !== 0?'76px':'50px'
                    }">
                      <el-button
                        @click="resetForm"
                        v-if="showQueryBtn&&selectedStrategies.length !== 0"
                        type="text"
                        icon="el-icon-error"
                      ></el-button>
                      <el-button
                        v-if="
                          showQueryBtn &&
                            showStrategyConfig &&
                            selectedStrategies.length !== 0
                        "
                        @click="$emit('searchSave')"
                        type="text"
                        icon="el-icon-folder-opened"
                      ></el-button>
                      <el-button
                        v-if="showQueryBtn"
                        @click="$emit('searchClick')"
                        type="text"
                        icon="el-icon-search"
                      ></el-button>
                    </div>
                  </div>
                </el-popover>
              </div>
              <div
                class="el-manager-ui__searchBox--config"
                v-if="showStrategyConfig"
              >
                <el-button
                  @click="stragegyListVisbile = true"
                  icon="el-icon-s-tools"
                  type="info"
                ></el-button>
              </div>
            </el-col>
          </el-row>
        </div>
      </el-form>
    </div>
    <slot name="extra"></slot>
    <slot name="center">
      <div class="el-manager-ui__tableInfo el-manager-ui__border">
      <el-row class="el-manager-ui__tableBox">
        <div class="el-manager-ui__tableBox--tableTabs" v-if="showTableTools">
          <div v-if="multipleSelection.length !== 0" class="header">
            <div>
              <span class="tableTabs__tools">已选中<span class="tableTabs__tools--number">{{ multipleSelection.length }}</span>项</span>
              <el-divider direction="vertical"></el-divider>
              <slot name="tableTools"> </slot>
            </div>
            <div>
              <el-button
                @click="clearMultipleSelection"
                type="text"
                icon="el-icon-close"
              ></el-button>
            </div>
          </div>
          <div v-else class="header">
            <el-button type="text" icon="el-icon-s-grid"></el-button>
          </div>
        </div>
        <div class="el-manager-ui__tableBox--tableContent">
          <el-table
            ref="table"
            :data="tableData"
            stripe
            :header-cell-style="{ fontSize: '13px' }"
            @selection-change="handleSelectionChange"
            @expand-change="handleExpandChange"
            @sort-change="handleSortChange"
            :height="tableMaxHeight"
          >
            <template v-for="(item, index) in columnItemsDisp">
              <template v-if="item.render">
                <el-table-column
                  :key="item.prop || index"
                  :prop="item.prop || ''"
                  :label="item.label || ''"
                  :width="item.width ? item.width + 'px' : ''"
                  :fixed="item.fixed || false"
                  :type="item.type || ''"
                  :align="item.align||'center'"
                  :sortable ="item.sortable||false"
                  :show-overflow-tooltip="item.showOverflowTooltip || false"
                >
                  <template slot-scope="scope">
                    <slot :name="item._key" :scope="scope"></slot>
                  </template>
                </el-table-column>
              </template>
              <template v-else>
                <el-table-column
                  :key="item.prop || index"
                  :type="item.type || ''"
                  :prop="item.prop || ''"
                  :label="item.label || ''"
                  :width="item.width ? item.width + 'px' : ''"
                  :fixed="item.fixed || false"
                  :sortable ="item.sortable||false"
                  :align="item.type == 'selection' ? '' : item.align?item.align:'center'"
                  :show-overflow-tooltip="item.showOverflowTooltip || false"
                ></el-table-column>
              </template>
            </template>
            <el-table-column align="right" fixed="right" width="40">
              <template slot="header" slot-scope="scope">
                <el-dropdown>
                  <span class="el-dropdown-link">
                    <el-button type="text" icon="el-icon-more"></el-button>
                  </span>
                  <el-dropdown-menu slot="dropdown" style="width:158px">
                    <div class="el-manager-ui__tableBox--dropdown">
                      <el-button
                        type="text"
                        icon="el-icon-download"
                        @click="$emit('allDownload')"
                        v-if="showDownloadBtn"
                        >全部导出</el-button
                      >
                      <el-button
                        type="text"
                        icon="el-icon-setting"
                        @click="columnsConfigVisible = true"
                        >自定义列</el-button
                      >
                      <slot name="tableDropdown"></slot>
                    </div>
                  </el-dropdown-menu>
                </el-dropdown>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-row>
    </div>
    </slot>
    <el-pagination
      v-if="showPagination"
      @current-change="handleCurrentChange"
      :current-page="pagination.current"
      @size-change="handleSizeChange"
      :page-sizes="[10, 50, 100]"
      :page-size="pagination.size"
      layout="total,sizes, prev, pager, next,jumper"
      :total="pagination.total"
    ></el-pagination>
    <manager-dialog
      :visible.sync="columnsConfigVisible"
      icon="el-icon-setting"
      title="自定义列"
      width="630px"
      :before-close="handleCloseConfig"
      class="el-columns-setting-transfer"
    >
      <div>
        <el-transfer
          :titles="['展示列', '移除列']"
          :filter-method="filterMethod"
          :props="{
            key: '_key',
            label: 'label'
          }"
          :data="sourceColumns"
          filter-placeholder="请输入列名"
          filterable
          ref="transferFilter"
          v-model="selectedColumns"
        >
        </el-transfer>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="setColums">保存设置</el-button>
      </span>
    </manager-dialog>
    <manager-dialog
      :visible.sync="stragegyListVisbile"
      icon="el-icon-setting"
      title="策略管理"
    ></manager-dialog>
  </div>
</template>
<script>
import { on, off } from 'ns-element/src/utils/dom';
import { isEmpty } from 'ns-element/src/utils/util';
export default {
  name: 'ManagerUi',
  componentName: 'ManagerUi',
  provide() {
    return {
      managerForm: this
    };
  },
  data() {
    return {
      collapseVisible: false,
      columnsConfigVisible: false,
      stragegyListVisbile: false,
      stragegyFormVisbile: false,
      tableMaxHeight: null,
      rowHeight: 55,
      multipleSelection: [],
      selectedStrategies: [],
      selectedColumns: [],
      columnItemsDisp: []
    };
  },
  props: {
    size: {
      type: String,
      default: 'small'
    },
    outerHeight: {
      type: Number,
      default: 50
    },
    rules: {
      // 表单校验规则
      type: Object,
      default: () => {}
    },
    showClose: {
      type: Boolean,
      default: false
    },
    showTableTools: {
      type: Boolean,
      default: true
    },
    loading: {
      // 全局loading
      type: Boolean,
      default: false
    },
    title: {
      // 标题
      tyle: String,
      default: ''
    },
    // -------搜索相关配置--------
    labelPosition: {
      // 表单域标签的位置
      type: String,
      default: 'right'
    },
    labelWidth: {
      // 表单域标签的宽度
      type: Number,
      default: 90
    },
    showQuery: {
      // 是否有查询框
      type: Boolean,
      default: true
    },
    showPagination: {
      // 是否有页码
      type: Boolean,
      default: true
    },
    showStrategyConfig: {
      // 是否有策略配置按钮
      type: Boolean,
      default: false
    },
    queryModel: {
      // 查询表单对应的数据
      type: Object,
      default: () => {}
    },
    queryItems: {
      // 查询表单渲染数据
      type: Array,
      default: () => []
    },
    showQueryBtn: {
      // 查询的按钮控制
      type: Boolean,
      default: true
    },
    showDownloadBtn: {
      // 导出按钮控制
      type: Boolean,
      default: true
    },
    showAddBtn: {
      // 新增按钮控制
      type: Boolean,
      default: true
    },
    // 查询所需要的一些数据----------------------
    staticData: {
      // 查询所需要的一些数据
      type: Object,
      default: () => {}
    },
    // table相关数据
    columnItems: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Array,
      default: () => []
    },
    pagination: {
      type: Object,
      default: () => {
        return {
          current: 1,
          size: 10,
          total: 0
        };
      }
    }
  },
  watch: {
    columnItems: {
      handler(newVal) {
        this.columnItemsDisp = newVal;
      },
      immediate: true
    }
  },
  mounted() {
    this.clientTableHeight();
    on(window, 'resize', this.clientTableHeight);
    this.$on('handleQueryChange', this.setQueryStrategies);
  },
  updated() {
    if (this.$refs.table) {
      this.$refs.table.doLayout();
    }
  },
  destroyed() {
    off(window, 'resize', this.clientTableHeight);
  },
  computed: {
    sourceColumns() {
      return this.columnItems.filter(item => item._key && item.label);
    },
    querySpreadSlotItems() {
      return this.queryItems.filter((item, index) => item.type === 'slot');
    }
  },
  methods: {
    setQueryStrategies({ key, label, value }) {
      if (!isEmpty(value)) {
        const index = this.selectedStrategies.findIndex(
          obj => obj.key === key
        );
        if (index === -1) {
          this.selectedStrategies.push({
            label: label,
            value: value,
            key
          });
        } else {
          this.selectedStrategies.splice(index, 1, {
            label: label,
            value: value,
            key
          });
        }
      } else if (this.selectedStrategies.findIndex(obj => obj.key === key) !== -1) {
        this.selectedStrategies.splice(
          this.selectedStrategies.findIndex(obj => obj.key === key),
          1
        );
      }
    },
    setColums() {
      if (this.handleCloseConfig()) {
        this.columnsConfigVisible = false;
        if (this.selectedColumns.length > 0) {
          this.columnItemsDisp = this.columnItems.filter(
            item => !this.selectedColumns.includes(item._key)
          );
        } else {
          this.columnItemsDisp = this.columnItems;
        }
      }
    },
    resetColums() {
      this.selectedColumns = [];
    },
    handleCloseConfig(done) {
      if (this.selectedColumns.length === this.sourceColumns.length) {
        this.$confirm('不能全部移除,至少展示一列!');
        return false;
      } else {
        this.$refs.transferFilter.clearQuery('left');
        this.$refs.transferFilter.clearQuery('right');
        done && done();
        return true;
      }
    },
    clientTableHeight() {
      this.tableMaxHeight =
        document.documentElement.clientHeight - this.outerHeight - 200;
    },
    filterMethod(query, item) {
      return item.label.indexOf(query) > -1;
    },
    clearMultipleSelection() {
      this.multipleSelection = [];
      this.$refs.table.clearSelection();
      this.$emit('clearSelection', this.multipleSelection);
    },
    handleTagClose(tag) {
      this.selectedStrategies.splice(this.selectedStrategies.indexOf(tag), 1);
      if (this.queryModel[tag.key] instanceof Array) {
        this.queryModel[tag.key] = [];
      } else {
        this.queryModel[tag.key] = null;
      }
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
      this.$emit('selection-change', val);
    },
    handleExpandChange(row, expand) {
      this.$emit('expandChange', row, expand);
    },
    handleSortChange({ column, prop, order }) {
      this.$emit('sortChange', { column, prop, order });
    },
    // 分页当前页改变时触发函数
    handleCurrentChange: function(currentPage) {
      this.pagination.current = currentPage;
      this.$emit('search');
    },
    // 分页每页显示数目改变时触发函数
    handleSizeChange: function(size) {
      this.pagination.size = size;
      this.$emit('search');
    },
    // 查询重置
    resetForm() {
      this.selectedStrategies = [];
      this.$refs.form.resetFields();
      this.$refs.strategyForm.resetForm();
      this.$emit('resetForm');
    },
    // validate methods
    validate(callback) {
      let flag = null;
      this.$refs['form'].validate(valid => {
        if (valid) {
          flag = true;
        } else {
          flag = false;
        }
      });
      callback.call(this, flag);
    },
    clearForm() {
      this.$refs['form'].resetFields();
    }
  }
};
</script>
