<template>
  <div class="xd-table-product">
    <div class="xd-table-product__table" :style="{ maxHeight: maxHeight }">
      <xd-table
        ref="table"
        :key="tableKey"
        v-if="headers.length > 0"
        :get-link="getLink"
        :headers="headers"
        :list="list"
        :is-border="border"
        @onClick="handleClickBtn"
        @change="handleInputChange"
      ></xd-table>
    </div>
    <div class="xd-table-product__btn">
      <el-button :disabled="disabled" type="primary" @click="handleOpen()">{{ btnName }}</el-button>
    </div>
    <xd-dialog
      :title="title"
      :width="width"
      :show.sync="dialogShow"
      v-if="dialogShow"
      @onClose="handleClose"
    >
      <div class="xd-table-product__search">
        <xd-search
          v-if="searchForm.length > 0"
          :list="searchForm"
          dateFilter
          v-model="searchParams"
          @onSearch="handleSearch"
          :remote-search="handleRemoteSearch"
        ></xd-search>
      </div>
      <div class="xd-table-product__content">
        <xd-table
          :key="tableDialogKey"
          :get-link="getLink"
          :selection-row-is-disabled="selectionRowIsDisabled"
          :list="ableDialogList"
          :headers="dialogHeader"
          :is-border="border"
          current-row-key="id"
          v-if="headers.length > 0"
          @onSelect="handleSelect"
        ></xd-table>
      </div>
      <div class="app-container__list-pagination">
        <xd-pagination-jfb
          :key="paginationKey"
          :next-page="nextPage"
          v-model="currentPage"
          :get-total="handleGedtCount"
          @onPagination="handlePagination"
        ></xd-pagination-jfb>
      </div>
      <template slot="btn">
        <el-button size="medium" @click="handleClose">取 消</el-button>
        <el-button
          size="medium"
          type="primary"
          :disabled="selectedList.length === 0"
          @click="handleCascadeCustom"
          >确 定</el-button
        >
      </template>
    </xd-dialog>
  </div>
</template>

<script>
import emitter from "element-ui/src/mixins/emitter";
import XdTable from "@/components/XdTable";
import XdDialog from "@/components/XdDialog";
import XdCascadePanel from "./XdCascadePanel";
import XdPagination from "@/components/XdPagination.vue";
import XdPaginationJfb from "../XdPaginationJfb.vue";
import XdSearch from "@/components/XdSearch";
import { Loading } from "element-ui";

export default {
  name: "XdTableProduct",
  components: {
    XdDialog,
    XdTable,
    XdCascadePanel,
    XdSearch,
    XdPagination,
    XdPaginationJfb,
  },
  mixins: [emitter],
  props: {
    defaultValue: {
      type: Array,
      default() {
        return [];
      },
    },

    maps: {
      type: Object | null,
      default() {
        return null;
      },
    },

    setting: {
      type: Object,
      default() {
        return {
          selectList: [],
          btnName: "指定区域",
          width: "600px",
          border: true,
          headers: [],
        };
      },
    },

    disabled: {
      type: Boolean,
      default: false,
    },

    size: {
      type: String,
      default: "medium", //medium / small / mini
    },

    placeholder: {
      type: Object,
      default() {
        return {};
      },
    },

    required: {
      type: Boolean,
      default: false,
    },

    //是否启用自定义校验器
    useCustomRules: {
      type: Boolean,
      default: false,
    },

    //数字字符串 转 数字
    isNumber: {
      type: Boolean,
      default: true,
    },

    //自定义方法
    handleCustom: {
      type: Function || null,
      default: null,
    },
  },
  data() {
    return {
      tableKey: "tableKey",
      btnName: "指定区域",
      border: true,
      headers: [],
      width: "600px",
      maxHeight: "300px",
      title: "选择配送区域",
      list: [], //已选中城市列表
      is_var_price: {}, //表单字段为价格

      //dialog and city select data
      dialogShow: false,
      dialogHeader: [],
      ableDialogList: [], //选择列表
      selectedList: [], //已选中选品结果
      tableDialogKey: "tableDialogKey",
      timer: null,

      //搜索
      searchForm: [], //搜索区域模块表单
      searchParams: null, // 搜索参数

      //分页参数
      initPage: false, //是否为首次加载
      currentPage: "1", //请求访问的页面
      nextPage: "", //下一页访问页码
      paginationKey: "paginationKey", //刷新插件key
      page_size: 20,
    };
  },

  created() {
    if (typeof this.handleCustom !== "function") {
      throw new Error(`this.handleCustom()自定义访问未定义`);
    }
    if (this.setting["width"] !== undefined) this.width = this.setting["width"];
    if (this.setting["maxHeight"] !== undefined)
      this.maxHeight = this.setting["maxHeight"];
    if (this.setting["title"] !== undefined) this.title = this.setting["title"];
    if (this.setting["border"] !== undefined)
      this.border = this.setting["border"];
    if (this.setting["btnName"] !== undefined)
      this.btnName = this.setting["btnName"];
    if (
      this.setting["headers"] &&
      this.$xdHelper.checkVarType(this.setting.headers) === "array"
    ) {
      this.headers = this.setting["headers"]
      this.dialogHeader = [{ type: "selection" }]
        .concat(this.setting["headers"])
        .map((item) => {
          if (item.prop === "operate") {
            let values = item.values.filter((val) => {
              return val.pos !== "delete";
            });
            return {
              ...item,
              width: item.width - 60,
              values: values,
              disabled:this.disabled
            };
          } else return item;
        });

    }

    if (
      this.setting["searchForm"] &&
      this.$xdHelper.checkVarType(this.setting.searchForm) === "array"
    ) {
      this.searchForm = this.setting["searchForm"];
    }

    this.handleMapToList();
  },

  methods: {
    selectionRowIsDisabled(row, index) {
      let tableData = this.$xdHelper.cloneDeep(this.$refs.table.getTableData());
      return (
        this.handleCustom({
          action: "disabled",
          data: { row, list: tableData },
        }).length === 0
      );
    },

    /**
     * @description 翻页处理方法
     * @param page {Number} 访问页面页码数
     */
    handlePagination(page) {
      // this.currentPage = page;
      this.handleSearch({ action: "pagination" });
    },

    /**
     * @description 搜索组件进行远程搜索处理方法
     */
    handleRemoteSearch({ query, prop }, cb) {
      let loading = Loading.service({});
      this.handleCustom({
        action: "remote-search",
        data: {
          params: { query, prop },
          cb: (res) => {
            cb(res);
            loading.close();
          },
        },
      });
    },

    handleGedtCount(cb1) {
      let loading = Loading.service({});
      this.handleCustom({
        action: "count",
        data: {
          data_type: "count",
          params: Object.assign(this.searchParams, {
            page_token: String(this.currentPage),
            page_size: this.page_size,
          }),
          cb: (res) => {
            if (typeof cb1 === "function") {
              cb1(res["total"]);
              loading.close();
              return;
            }
          },
        },
      });
    },

    handleSearch({ action }) {
      //搜索或者重置页码重置为1
      if (action === "search" || action === "reset") this.currentPage = '1';

      let loading = Loading.service({});
      this.handleCustom({
        action: action==='pagination'?action:'search',
        data: {
          params: Object.assign(this.searchParams, {
            page_token: String(this.currentPage),
            page_size: this.page_size,
          }),
          cb: (res) => {
            this.ableDialogList = res.list;
            this.nextPage = res.nextPage;
            if(action!=='pagination') {
              this.paginationKey = Date.now();
            }
            this.tableDialogKey = this.$xdHelper.randomChar(20);
            loading.close();
          },
        },
      });
    },

    handleSelect({ select }) {
      this.selectedList = this.$xdHelper.cloneDeep(select);
    },

    handleInputChange() {
      this.$nextTick(() => {
        this.update();
      });
    },

    handleClose() {
      this.dialogShow = false;
      this.selectedList = [];
    },

    handleCascadeCustom() {
      if (typeof this.handleCustom === "function") {
        this.handleCustom({
          action: "select",
          data: {
            list: this.selectedList,
            cb: (items) => {
              this.list = items.concat(this.list);
              this.tableKey = this.$xdHelper.randomChar(20);
              this.handleClose();
              this.$nextTick(() => {
                this.update();
              });
            },
          },
        });
      }
    },

    handleOpen() {
      this.dialogShow = true;
    },

    /**
     * @description 处理点击事件按钮跳转
     * @param row
     * @param value
     * @param index
     * @param rowIndex
     */
    handleClickBtn({ row, value, index, rowIndex }) {
      if (value.pos === "delete") {
        let tableData = this.$xdHelper.cloneDeep(
          this.$refs.table.getTableData()
        );
        tableData.splice(rowIndex, 1);
        this.list = tableData;
        this.tableKey = this.$xdHelper.randomChar(20);
        this.$nextTick(() => {
          this.update();
        });
      } else {
        this.handleCustom({
          action: "button",
          data: { row, value, index, rowIndex },
        });
      }
    },

    /**
     * @description 处理点击链接按钮跳转
     * @param row
     * @param value
     * @param index
     */
    getLink({ row, value, index }) {
      if (typeof this.handleCustom === "function") {
        return this.handleCustom({
          action: "link",
          data: { row, value, index },
        });
      }
      return `/`;
    },

    /**
     * @description 返回映射关系对象数据（需要自己实现）
     * 把内部数据转化为返回数据格式
     */
    handleListToMap() {
      return this.$xdHelper.cloneDeep(this.$refs.table.getTableData());
    },

    /**
     * @description 初始化映射关系到数据列表(需要自己实现)
     * 把默认数据转化为内部数据
     */
    handleMapToList() {
      if (
        this.defaultValue &&
        this.$xdHelper.checkVarType(this.defaultValue) === "array" &&
        this.defaultValue.length > 0
      ) {
        this.list = this.$xdHelper.cloneDeep(this.defaultValue);
        this.$nextTick(() => {
          this.update();
        });
      }
    },

    //插件系统方法///////////////////////////////////////
    /**
     * @description 获取Maps中键与值
     * @param type {boolean} 返回值类型  true=>获取键  false=>值
     * @param keyword {string} 查找关键字
     * @return {null|string} null=>未找到  string=>找到
     */
    getMap(keyword, type) {
      let maps = null;
      let value = null;
      if (this.maps !== null && !this.$xdHelper.isEmpty(this.maps)) {
        maps = this.$xdHelper.cloneDeep(this.maps);
      }

      //先默认maps关系中找
      Object.keys(this.defaultMap).map((ky) => {
        //获取键
        if (type) {
          if (this.defaultMap[ky] === keyword) {
            value = ky;
          }
        } else {
          if (this.defaultMap[keyword]) value = this.defaultMap[keyword];
        }
      });

      //无外部map关系并且在默认关系表中无键
      if (value === null && maps === null) {
        //console.log('1')
        return null;
      }

      //无外部map关系并且在默认关系表中键
      if (value !== null && maps === null) {
        //console.log('2', value)
        return value;
      }

      //有外部map关系进行查找
      Object.keys(maps).map((ky) => {
        //获取键
        if (type) {
          if (maps[ky] === keyword) {
            value = ky;
          }
        } else {
          if (this.maps[keyword]) value = this.maps[keyword];
        }
      });
      //console.log('3')
      return value;
    },

    /**
     * @description 需要校验检查参数是正确处理方法
     */
    checkParams() {
      if (!this.required) return this.handleListToMap();

      //校验成功
      return this.handleListToMap();
    },

    /**
     * @description 双向绑定数据处理
     */
    update() {
      this.$emit("input", this.checkParams());
      if (this.$parent.$options["componentName"] === "ElFormItem") {
        this.dispatch("ElFormItem", "el.form.change", [this.checkParams()]);
      }
    },
  },
};
</script>

<style scoped lang="scss">
.xd-table-product {
  &__search {
    margin-bottom: 0;
  }

  &__content {
    margin-bottom: 20px;
    max-height: 400px;
    overflow-y: auto;
  }

  &__table {
    overflow-y: auto;
  }

  &__btn {
    padding-top: 10px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    & > *:nth-child(2) {
      margin-left: 10px;
      color: #999;
      & span {
        padding: 0 2px;
      }
    }
  }
}

@media screen and (max-width: 768px) {
  .xd-table-product {
    &__search {
      margin-bottom: 0;
    }

    &__content {
      margin-bottom: 10px;
    }
  }
}
</style>
