<template>
  <section class="ces-table-page">
    <!-- 数据表格 -->
    <section class="ces-table">
      <div class="ces_toolbar">
        <el-button
          v-if="filterList && filterList.length"
          size="small"
          style="float: left;"
          @click="filterAction"
        >
          {{ showFliterList ? "收起" : "筛选" }}
          <i
            class="el-icon--right"
            :class="
              showFliterList ? 'el-icon-caret-bottom' : 'el-icon-caret-top'
            "
          ></i>
        </el-button>
        <el-button
          v-if="addRowBtn"
          icon="el-icon-plus"
          size="small"
          type="primary"
          @click="addRow()"
          class="ces_toolbar_btn"
          >新增</el-button
        >
        <el-input
          prefix-icon="el-icon-search"
          v-if="searchShow"
          v-model="search"
          placeholder="请输入账号、中文名"
          style="max-width:220px;"
          size="mini"
          @input="searchVal"
          class="ces_toolbar_inp"
        ></el-input>
      </div>
      <ul
        class="ces_filter_container"
        ref="filterContainer"
        v-if="filterList && filterData && filterToggle"
        v-show="showFliterList"
      >
        <li v-for="(item, index) in filterList" :key="'f_l_' + index">
          <div class="ces_filter_name">
            <span v-text="item.name + '：'"></span>
          </div>
          <ul class="ces_filter_data">
            <li
              v-for="(v, i) in item.data"
              :key="'f_l_d_' + index + '_' + i"
              v-show="filterToggle[item.prop] || i < filterLength"
            >
              <a
                :class="{ current: isCurrentFilter(item.prop, v) }"
                @click.prevent="selectFilter(item.prop, v)"
                v-text="v"
              ></a>
            </li>

            <div
              class="toggle_bar"
              v-if="item.data.length > filterLength"
              @click="filterToggleAction(item.prop)"
            >
              <span>{{ filterToggle[item.prop] ? "收起" : "展开" }}</span>
              <i
                :class="
                  filterToggle[item.prop]
                    ? 'el-icon-caret-bottom'
                    : 'el-icon-caret-top'
                "
              ></i>
            </div>
          </ul>
        </li>
      </ul>
      <el-table
        :data="selectedTabsPage"
        :size="size"
        :border="border"
        @select="select"
        @select-all="selectAll"
        :defaultSelections="defaultSelections"
        element-loading-text="加载中..."
        :empty-text="emptyText"
        :stripe="stripe"
        row-key="id"
        :show-header="showHeader"
        default-expand-all
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        ref="cesTable"
        :class="radius ? 'table_radius' : ''"
        :header-cell-class-name="headerCellClassName"
        v-cloak
      >
        <el-table-column
          v-if="isSelection"
          type="selection"
          align="center"
        ></el-table-column>
        <!-- 序号 -->
        <el-table-column
          v-if="isIndex"
          type="index"
          :label="indexLabel"
          width="80"
          align="center"
        ></el-table-column>

        <!-- 数据栏 -->
        <el-table-column
          v-for="(item, index) in headers"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :align="item.align"
          :min-width="item.minWidth"
          :render-header="item.require ? renderHeader : null"
        >
          <template slot-scope="scope">
            <!-- 操作按钮 -->
            <span v-if="item.type === 'Button'">
              <b v-for="(btn, key) in item.btnList" :key="key">
                <em v-if="btn.label == '分配'">
                  <em
                    v-if="btn.label == '分配' && scope.row.state == 0"
                    class="cur_pointer"
                    style="color: #0f2683"
                    @click="handleClick(btn.type, scope.row)"
                  >
                    分配
                  </em>
                  <em v-if="btn.label == '分配' && scope.row.state == 1">
                    已分配
                  </em>
                </em>

                <em
                  class="cur_pointer"
                  v-else-if="btn.label == '删除' && btn.local"
                  :class="btn.type"
                  :style="{
                    color: btn.label == '删除' ? '#830f53' : '#0f2683',
                  }"
                  @click="deleteLocal(scope)"
                  >{{ btn.label }}</em
                >

                <em
                  class="cur_pointer"
                  v-else
                  :class="btn.type"
                  :style="{
                    color: btn.label == '删除' ? '#830f53' : '#0f2683',
                  }"
                  @click="handleClick(btn.type, scope.row)"
                  >{{ btn.label }}</em
                >

                <em v-if="btn.line" style="padding:0 20px;color:#edf0ff">
                  {{ btn.line }}
                </em>
              </b>
            </span>
            <!--href 链接-->
            <v-apaas-table-umhref
              v-else-if="item.type == 'href'"
              :header="item"
              :row="scope.row"
              :detailsUrl="detailsUrl"
            ></v-apaas-table-umhref>
            <!-- could edit -->
            <v-apaas-table-input
              v-else-if="item.type === 'input'"
              :item="helper.GetProperty(scope.row, item.prop)"
              :header="item.prop"
              :rowId="scope.$index"
              :couldNotEdit="couldNotEdit"
              @changeInputValue="changeInputValue"
            ></v-apaas-table-input>
            <!-- could select -->
            <v-apaas-table-select
              v-else-if="item.type === 'select'"
              :item="helper.GetProperty(scope.row, item.prop)"
              :header="item.prop"
              :selectArr="item.selectArr"
              :rowId="scope.$index"
              :couldNotEdit="couldNotEdit"
              @changeInputValue="changeInputValue"
            ></v-apaas-table-select>
            <!-- popover -->
            <el-popover
              v-else-if="item.type === 'popover'"
              placement="top-start"
              trigger="hover"
              :content="scope.row[item.prop]"
            >
              <div slot="reference" class="overlit">
                {{ scope.row[item.prop] }}
              </div>
            </el-popover>
            <!-- others -->
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>
      </el-table>
    </section>
    <!-- 分页 -->
    <section class="ces-pagination" v-if="paginationShow">
      <div class="ces_page_total">共 {{ pagination.total }} 个条目</div>
      <div class="ces_page_item">
        <div class="ces_page_num" v-if="pageSizeShow">
          <div>每页行数：</div>
          <div class="ces_page_num_sel">
            <el-select
              v-model="pagination.rowsPerPage"
              placeholder="请选择"
              size="small"
              @change="handleSizeChange"
            >
              <el-option
                v-for="item in pageOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </div>
        </div>
        <div class="ces_page_control">
          <el-button
            icon="el-icon-arrow-left"
            circle
            size="mini"
            @click="handleCurrentChange(-1)"
            :disabled="pagination.page == 1"
          ></el-button>
          &nbsp;&nbsp;第{{ pagination.page }}页 / 共{{
            Math.ceil(pagination.total / pagination.rowsPerPage)
          }}页
          <el-button
            icon="el-icon-arrow-right"
            circle
            size="mini"
            @click="handleCurrentChange(1)"
            :disabled="
              pagination.page >=
                Math.ceil(pagination.total / pagination.rowsPerPage)
            "
          ></el-button>
        </div>
      </div>
    </section>
  </section>
</template>

<script>
import services from "@/services";
import tableInput from "@/components/table-input";
import tableSelect from "@/components/table-select";
import helper from "@/services/helper";
import DConfirm from "@/components/dialog-remove";
import tableUmhref from "@/components/table-umhref";
export default {
  components: {
    "v-apaas-table-input": tableInput,
    "v-apaas-table-select": tableSelect,
    "v-apaas-table-umhref": tableUmhref,
    "d-confirm": DConfirm,
  },
  props: {
    // 表格型号：mini,medium,small
    size: { type: String, default: "medium" },
    loading: { type: Boolean, default: false },
    // 表格数据
    headers: { type: Array, default: () => [] },
    // 表格列配置
    // tableData: { type: Array, default: () => [] },
    // 是否显示表格复选框
    isSelection: { type: Boolean, default: false },
    defaultSelections: { type: [Array, Object], default: () => null },
    // 是否显示表格索引
    isIndex: { type: Boolean, default: false },
    indexLabel: { type: String, default: "序号" },
    // 是否显示分页
    // isPagination: { type: Boolean, default: true },
    // // 分页数据
    // pagination: {
    //   type: Object,
    //   default: () => ({ pageSize: 10, pageNum: 1, total: 0 })
    // },
    searchShow: {
      type: Boolean,
      default: false,
    },
    url: {
      type: String,
      default: "",
    },
    detailsUrl: {
      type: String,
      default: "",
    },
    rowprop: {
      type: String,
      default: "",
    },
    ready: {
      type: Boolean,
      default: false,
    },
    addRowBtn: {
      type: Boolean,
      default: false,
    },
    couldNotEdit: {
      type: Boolean,
      default: false,
    },
    refreshInit: { type: Boolean },
    sortBy: {
      type: String,
      default: "",
    },
    searchNoName: { type: Boolean, default: false },
    emptyText: {
      type: String,
      default: "暂无数据",
    },
    autoAdd: {
      type: Boolean,
      default: false,
    },
    border: {
      type: Boolean,
      default: false,
    },
    stripe: {
      type: Boolean,
      default: false,
    },
    radius: {
      type: Boolean,
      default: false,
    },
    pageSizeShow: {
      type: Boolean,
      default: false,
    },
    paginationShow: {
      type: Boolean,
      default: false,
    },
    headerCellClassName: {
      type: String,
      default: "",
    },
    filterList: {
      type: Array,
      default: null,
    },
    showHeader: {
      type: Boolean,
      default: true,
    },
    datas: {
      type: Array,
      default: null,
    },
  },
  data() {
    return {
      all_url: "",
      pagination: {
        rowsPerPage: 10,
        page: 1,
        total: 0,
      },
      delSelect: null,
      helper: helper,
      label: null,
      selectedTabsPage: [],
      pageOptions: [
        {
          value: "10",
          label: "10",
        },
        {
          value: "20",
          label: "20",
        },
        {
          value: "50",
          label: "50",
        },
      ],
      search: "",
      times: null,
      showFliterList: false,
      filterData: null, // 筛选条件
      filterToggle: null, // 控制筛选条件的展开和收起
      filterLength: 0, // 每行最多可容纳多少个过滤条件
    };
  },
  mounted() {
    this.getDataFromApiSync();
    this.initFilterData();

    window.addEventListener("resize", this.getFilterLength);
  },
  destroyed() {
    window.removeEventListener("resize", this.getFilterLength);
  },
  watch: {
    refreshInit: {
      handler(val) {
        if (val) {
          this.getDataFromApiSync();
        }
      },
    },
    url: {
      handler(val) {
        this.getDataFromApiSync();
      },
      deep: true,
    },
    filterList: {
      handler(val) {
        this.initFilterData();
      },
      deep: true,
    },
  },
  methods: {
    //本地删除
    deleteLocal(val) {
      this.selectedTabsPage.splice(val.$index, 1);
    },
    // get data
    getDataFromApiSync() {
      console.log("get data >>>");
      if (this.url == "") {
        // console.log(this.emptyText);
        // the if statement is to choose which data could be show, only used for test and template
        this.selectedTabsPage = [];
        if (this.datas) {
          this.selectedTabsPage = this.datas;
        }
        this.pagination.total = 0;
        if (this.autoAdd) {
          this.addRow();
        }
      } else {
        this.getDataFromApi().then(
          (data) => {
            this.selectedTabsPage = JSON.parse(JSON.stringify(data.newArr));
            this.pagination.total = data.total;
            if (this.autoAdd) {
              this.addRow();
            }
          },
          (err) => {
            console.log("失败" + err);
          }
        );
      }
    },
    // get data from api
    getDataFromApi() {
      return new Promise((resolve, reject) => {
        const { page, rowsPerPage } = this.pagination;
        this.all_url = `/static/data.json`;
        this.$http
          .get(this.all_url)
          .then((response) => {
            let newArr = response.data.data[this.url];
            // if it is true url, total is response's total
            let total = newArr.length;
            resolve({ newArr, total });
          })
          .catch(function(response) {
            // this.loading = false;
            reject(response);
          });
      });
    },
    // search debonce 500ms
    searchVal() {
      if (this.times !== null) clearTimeout(this.times);
      this.times = setTimeout(() => {
        this.getDataFromApiSync();
      }, 500);
    },
    // 表格勾选
    select(rows, row) {
      this.$emit("select", rows, row);
    },
    // 全选
    selectAll(rows) {
      this.$emit("select", rows);
    },
    handleCurrentChange(val) {
      this.pagination.page += val;
      this.getDataFromApiSync();
      this.$emit("refresh");
    },
    handleSizeChange(val) {
      this.pagination.rowsPerPage = val;
      this.getDataFromApiSync();
      this.$emit("refresh");
    },
    renderHeader(h, obj) {
      console.log(obj.column);
      return h("span", { class: "ces-table-require" }, obj.column.label);
    },
    refreshuseList() {
      this.$message({
        showClose: true,
        message: this.label + "成功",
        type: "success",
      });
    },
    switchChange(val) {
      this.$emit("handleSwitch", val);
    },
    reftableList() {},
    // another button in options
    handleClick(type, val) {
      this.$emit(type, val);
    },
    // 表格编辑修改数据
    changeInputValue(val) {
      // You can delete the row when the row of data is empty, but I didn't do that
      // console.log(this.$refs.cesTable)
      this.selectedTabsPage[val.rowId][val.header] = val.inputValue;
      if (
        this.autoAdd &&
        val.inputValue != "" &&
        val.rowId + 1 == this.selectedTabsPage.length
      ) {
        this.addRow();
      }
    },
    // 新增表格行
    addRow() {
      // at first, you should promise all colum in your table could be edit
      // this code is low level, you could make it stronger
      // use tableData[0] as template to edit
      let newRow = {};
      for (var item in this.selectedTabsPage[0]) {
        newRow[item] = "";
      }
      this.selectedTabsPage.push(newRow);
    },
    // get now table data
    getTableData() {
      return this.selectedTabsPage;
    },
    isCurrentFilter(prop, filter) {
      return (
        this.filterData &&
        this.filterData[prop] &&
        this.filterData[prop].indexOf(filter) > -1
      );
    },
    filterAction() {
      this.showFliterList = !this.showFliterList;
      this.getFilterLength();
    },
    getFilterLength() {
      if (this.showFliterList) {
        this.$nextTick(() => {
          let width =
            this.$refs.filterContainer.getBoundingClientRect().width -
            20 * 2 - // 两侧padding
            100 - // 左侧标题
            20 - // 距左侧标题的边距
            110; // 折叠按钮的宽度

          this.filterLength = Math.floor(width / 110);
          // console.log("每行最多可容纳" + this.filterLength + "个filter");
        });
      }
    },
    filterToggleAction(prop) {
      this.$set(this.filterToggle, prop, !this.filterToggle[prop]);
    },
    initFilterData() {
      if (this.filterList && this.filterList.length) {
        this.filterData = {};
        this.filterToggle = {};
        this.filterList.forEach((item) => {
          this.$set(this.filterData, item.prop, []);
          this.$set(this.filterToggle, item.prop, false);
        });
      }
    },
    selectFilter(prop, filter) {
      if (this.isCurrentFilter(prop, filter)) {
        this.filterData[prop].splice(this.filterData[prop].indexOf(filter), 1);
      } else {
        this.filterData[prop].push(filter);
      }
      console.log(this.filterData);
    },
  },
};
</script>

<style>
.ces-table .el-table::before {
  height: 0 !important;
}
.ces-table .el-table th.gutter {
  display: table-cell !important;
}
.ces-table .el-table colgroup.gutter {
  display: table-cell !important;
}
.ces-table .el-table td,
.ces-table .el-table th.is-leaf {
  border-bottom: none !important;
}
.ces-table .el-table--border td,
.ces-table .el-table th.is-leaf {
  border-bottom: 1px solid #ebeef5 !important;
}
/* .ces-table .el-table--enable-row-hover, */
.ces-table .el-table tbody tr:hover > td {
  background-color: #e4ecf8 !important;
  /* border-top: 1px solid #b9cefa !important;
  border-bottom: 1px solid #b9cefa !important; */
}
.ces-table .theme--light.el-table tbody tr:not(:last-child) {
  border-bottom: none;
}
.ces-table .el-table th > .cell {
  color: #1a2236;
}
.ces-table .el-table th > .cell,
.ces-table .el-table td > .cell {
  /* text-align: center; */
  font-size: 14px;
}
.ces-table .el-table tr {
  color: #58617a;
}
.ces-table .el-table__empty-text {
  color: #58617a;
  font-size: 14px;
}
em {
  font-style: normal;
  user-select: none;
}
.cur_pointer {
  cursor: pointer;
}
.ces-table .el-table--mini td,
.ces-table .el-table--mini th {
  padding: 11px 0 !important;
}
.ces-table .el-table--border::after,
.ces-table .el-table--group::after,
.ces-table .el-table::before {
  background: #fff;
}
.ces-table .switchStyle .el-switch__label {
  position: absolute;
  display: none;
  color: #fff;
}
.ces-table .switchStyle .el-switch__label--left {
  z-index: 9;
  left: 6px;
  top: -1px;
}
.ces-table .switchStyle .el-switch__label--right {
  z-index: 9;
  left: -14px;
  top: -1px;
}
.ces-table .switchStyle .el-switch__label.is-active {
  display: block;
}
.ces-table .switchStyle.el-switch .el-switch__core,
.ces-table .el-switch .el-switch__label {
  width: 50px !important;
}
.ces-table .el-switch__core {
  background: #f8f9fd !important;
  border: 1px solid #8890a7 !important;
}
.ces-table .el-switch__core:after {
  background: #8890a7 !important;
}
.ces-table .el-switch.is-checked .el-switch__core {
  background: #f8f9fd !important;
  border: 1px solid #5c82ff !important;
}
.ces-table .el-switch.is-checked .el-switch__core:after {
  background: #5c82ff !important;
}
.ces-table .el-switch__label * {
  font-size: 10px !important;
  font-weight: 800;
}
.ces-table .el-switch .el-switch__label {
  color: #8890a7 !important;
}
.ces-table .el-switch.is-checked .el-switch__label {
  color: #5c82ff !important;
}
.ces-table .el-switch:hover {
  opacity: 0.8;
}
.chName.is-dark {
  background: #5c82ff !important;
}
.chName[x-placement^="top"] .popper__arrow,
.chName[x-placement^="top"] .popper__arrow::after {
  border-top-color: #5c82ff !important;
}
.el-table__row--striped td {
  background: #f8f9fd !important;
}
/* .el-table th>.cell {
  padding-left: 14px;
} */
.el-table__placeholder {
  display: inline-block;
  width: 40px;
}
.th_pink {
  background-color: #faf2e2 !important;
}
.ces_page_control .el-button {
  border: 0;
}
.ces_page_num .el-input__inner {
  border: 0;
  padding: 0;
}
</style>
<style scoped>
.ces-table {
  position: relative;
}
.ces_toolbar {
  position: absolute;
  top: -40px;
  right: 0;
  left: 0;
  text-align: right;
}
.ces_toolbar .ces_toolbar_btn {
  margin-right: 10px;
}
.ces_toolbar .ces_toolbar_inp {
  margin-right: 10px;
}
.ces-pagination {
  margin-top: 20px;
  padding-bottom: 20px;
  font-size: 14px;
  padding: 0 5%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
/* .ces_page_total {
} */
.ces_page_num {
  width: 140px;
  margin-right: 20px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.ces_page_num_sel {
  width: 50px;
  font-size: 14px;
  position: relative;
  top: 1px;
}
.table_radius {
  border-radius: 8px;
}
.overlit {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ces_filter_container {
  background-color: #f7f8f9;
  padding: 14px 19px;
  border: 1px solid #e3e5ef;
  border-radius: 6px;
  margin: 0 0 10px;
}
.ces_filter_container > li {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  padding-top: 12px;
}
.ces_filter_name {
  width: 100px;
  height: 30px;
  flex-shrink: 0;
  text-align: right;
  font-size: 14px;
  line-height: 30px;
  font-weight: bold;
  color: #1a2236;
}
.ces_filter_data {
  width: calc(100% - 120px);
  padding-right: 110px;
  box-sizing: border-box;
  margin-left: 20px;
  flex-grow: 1;
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  padding-bottom: 11px;
  position: relative;
}
.ces_filter_container > li:not(:last-child) > .ces_filter_data {
  border-bottom: 1px solid #e9ecf3;
}
.ces_filter_data > li {
  flex-shrink: 0;
  padding-right: 20px;
}
.ces_filter_data > .toggle_bar {
  height: 30px;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 14px;
  line-height: 30px;
  color: #0f2683;
  cursor: pointer;
}
.ces_filter_data > li > a {
  display: block;
  height: 30px;
  width: 90px;
  box-sizing: border-box;
  border-radius: 12px;
  text-align: center;
  cursor: pointer;
  font-size: 14px;
  line-height: 30px;
  color: #58617a;
}
.ces_filter_data > li > a.current {
  background-color: #515fe7;
  color: #f4f7fc;
}
.ces_page_item {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
</style>
