<template>
  <!-- <div> -->
  <el-table
    :id="_uid"
    v-loading="tableLoading"
    element-loading-text="拼命加载中..."
    @sort-change="sortChange"
    @selection-change="handleSelectionChange"
    ref="multipleTable"
    :data="tableData"
    height="85%"
    row-key="id"
    stripe
    border
    style="width: 100%"
    :tree-props="treeProps"
    :cell-style="cellStyle"
  >
    <el-table-column v-if="selectionTable" fixed="left" type="selection" />
    <el-table-column v-if="isShowIndex" type="index" fixed="left" label="序号" width="50" />
    <el-table-column
      v-for="(item, index) in TableSize"
      :key="index"
      :prop="item.showProp ? item.prop + '.' + item.showProp : item.prop"
      :sortable="item.sortable"
      :fixed="item.fixed"
      :show-overflow-tooltip="true"
      :width="item.width"
      align="center"
    >
      <template #header>
        <span>{{ item.label }}</span>
        <i style="color: #f56c6c" v-if="item.rules && requiredRules">*</i>
      </template>
      <template slot-scope="scope">
        <el-form>
        <el-form-item
          v-if="item.type == 'input'"
          :onkeyup="itemOnKeyUp(item,searchData[item.prop])"
          :prop="'details.' + scope.$index + '.' + item.prop"
          :rules="item.rules"
        >
          <el-input
            :placeholder="'请输入' + item.label"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            v-model="scope.row[item.prop]"
            @blur="
              inputPlaceholder($event, item, 'blur',scope.row)
            "
            @focus="inputPlaceholder($event, item, 'focus')"
            clearable
          >
          </el-input>
        </el-form-item>
        <!-- 输入框(数字) onkeyup: 正则表达式，用于前端输入校验工作-->
        <el-form-item
          v-if="item.type == 'inputNumber'"
          :prop="'details.' + scope.$index + '.' + item.prop"
          :rules="item.rules"
        >
          <el-input
            v-model="searchData[item.prop]"
            :maxlength="item.maxlength"
            :onkeyup="typeNumberOnkeyup(item,searchData[item.prop])"
            clearable
            :disabled="Boolean(item.disabled)"
            :placeholder="'请输入' + item.label"
            :prefix-icon="item.icon"
            :show-password="item.showPassword"
            @change="changeInput(item.prop,$event)"
            @clear="clearInput(item.prop,$event)"
            @blur="
              inputPlaceholder($event, item, 'blur',searchData)
            "
            @focus="inputPlaceholder($event, item, 'focus')"
          ></el-input>
        </el-form-item>
        <el-form-item
          v-if="item.type == 'objectInput'"
          :prop="
            'details.' + scope.$index + '.' + item.prop + '.' + item.showProp
          "
          :rules="item.rules"
        >
          <el-input
            :placeholder="'请输入' + item.label"
            v-model="scope.row[item.prop][item.showProp]"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            @blur="
              inputPlaceholder($event, item, 'blur', scope.row)
            "
            @focus="inputPlaceholder($event, item, 'focus')"
            clearable
          >
          </el-input>
        </el-form-item>
        <!-- 下拉框 -->
        <el-select
          v-if="item.type === 'select'"
          v-model="scope.row[item.prop]"
          :loading="selectLoading"
          :clearable="item.clearable"
          :multiple="item.multiple"
          :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
          :filterable="item.filterable"
          :allow-create="item.allowCreate"
          style="width: 100%"
          :placeholder="'请输入' + item.label"
        >
          <el-option
            v-for="(op, index) in selectOptions(item.options) ||
            searchOptions['options']"
            :label="op[item.optionsLabel] || op.label"
            :value="op[item.optionsValue] || op.value"
            :key="index"
          ></el-option>
        </el-select>
        <!--对象下拉框 -->
        <el-select
          v-if="item.type === 'objectSelect'"
          v-model="scope.row[item.prop][item.showProp]"
          :loading="selectLoading"
          :clearable="item.clearable"
          :multiple="item.multiple"
          :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
          :filterable="item.filterable"
          :allow-create="item.allowCreate"
          style="width: 100%"
          :placeholder="'请输入' + item.label"
        >
          <el-option
            v-for="(op, index) in selectOptions(item.options) ||
            searchOptions['options']"
            :label="op[item.optionsLabel] || op.label"
            :value="op[item.optionsValue] || op.value"
            :key="index"
          ></el-option>
        </el-select>
        <!--查询下拉-->
        <el-form-item
          v-if="item.type === 'autocomplete'"
          :prop="'details.' + scope.$index + '.' + item.prop"
          :rules="item.rules"
        >
          <el-autocomplete
            class="inline-input"
            style="width: 100%"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            v-model="scope.row[item.prop]"
            :fetch-suggestions="
              (queryString, cb) => {
                querySearch(queryString, cb, item, scope);
              }
            "
            :placeholder="'请输入' + item.label"
            @select="handleSelect($event, item, scope)"
          >
            <!-- <template slot-scope="{item}">
                 <div class="name" style="color:green">{{item.value = item.name}}</div>
                 <div class="name" >{{item.address = item.code}}</div>
            </template> -->
            <el-button
              v-if="item.click"
              slot="append"
              icon="el-icon-search"
              @click="item.click({ scope, item })"
              style="color: #1890ff; background-color: #ffffff"
            ></el-button>
          </el-autocomplete>
        </el-form-item>
        <!-- 对象查询下拉 -->
        <el-form-item
          v-if="item.type === 'objectAutocomplete'"
          :prop="
            'details.' + scope.$index + '.' + item.prop + '.' + item.showProp
          "
          :rules="item.rules"
        >
          <el-autocomplete
            class="inline-input"
            style="width: 100%"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            v-model="scope.row[item.prop][item.showProp]"
            :fetch-suggestions="
              (queryString, cb) => {
                querySearch(queryString, cb, item, scope);
              }
            "
            :placeholder="'请输入' + item.label"
            @select="handleSelect($event, item, scope)"
          >
            <!-- <template slot-scope="{item}">
                 <div class="name" style="color:green">{{item.value = item.name}}</div>
                 <div class="name" >{{item.address = item.code}}</div>
            </template> -->
            <el-button
              v-if="item.click"
              slot="append"
              icon="el-icon-search"
              @click="item.click({ scope, item })"
              style="color: #1890ff; background-color: #ffffff"
            ></el-button>
          </el-autocomplete>
        </el-form-item>
        <!-- <el-form-item v-if="item.type == 'inputEnum'" :prop="item.prop">
          <el-input
            placeholder="请输入内容"
            v-model="scope.row[item.prop]"
            clearable
          >
          </el-input>
        </el-form-item> -->

        <el-form-item
          v-if="item.type == 'dateTimeInput'"
          :prop="'details.' + scope.$index + '.' + item.prop"
          :rules="item.rules"
        >
          <el-date-picker
            type="datetime"
            v-model="scope.row[item.prop]"
            placeholder="选择日期"
            style="width: 100%"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            value-format="yyyy-MM-ddTHH:mm:ss.sssZ"
            format="yyyy-MM-dd"
          ></el-date-picker>
        </el-form-item>
        <el-form-item
          v-if="item.type == 'objectDateTimeInput'"
          :prop="'details.' + scope.$index + '.' + item.prop + '.' + item.showProp"
          :rules="item.rules"
        >
          <el-date-picker
            type="datetime"
            v-model="scope.row[item.prop][item.showProp]"
            placeholder="选择日期"
            style="width: 100%"
            :disabled="Boolean(item.disabled) || Boolean(scope.row['disabled'])"
            value-format="yyyy-MM-ddTHH:mm:ss.sssZ"
            format="yyyy-MM-dd"
          ></el-date-picker>
        </el-form-item>
        <!-- table表添加按钮事件 v-show="scope.row.number == 'PRJ202210060001'" -->
        <el-form-item v-if="item.type == 'button'" >
          <el-button
            v-show="scope.row[item.prop]==undefined?true:false"
            type="primary"
            size="mini"
            @click="buttonClick(scope.row, scope.$index, item.label)"
          >{{item.label}}</el-button>
        </el-form-item>

        <span v-if="item.type == 'object'">
          {{ scope.row[item.prop] ? scope.row[item.prop][item.showProp] : "" }}
        </span>
        <span v-if="item.type == 'objectDateTime'">
          {{ scope.row[item.prop]? scope.row[item.prop][item.showProp]: "" | formatDate }}
        </span>
        <span v-if="item.type == 'dateTime'">
          {{ scope.row[item.prop] | formatDate }}
        </span>
        <!-- 调用主表信息 -->
        <span v-else-if="item.type && item.type == 'outerMainFilter'">
          {{ propsData[item.showProp] }}
        </span>
        <el-tag
          v-if="item.type == 'tagFilter'"
          :effect="'dark'"
          size="medium"
          class="tagFilterTypeDarkItem"
          :color="scope.row[item.prop] | trigger(item.filters, 'background')"
        >
          {{ scope.row[item.prop] | trigger(item.filters, "label") }}
        </el-tag>
        <span
          v-if="item.type == 'filter'"
          :style="scope.row[item.prop]"
        >
          {{ scope.row[item.prop] | trigger(item.filters, "label", item.dictType) }}
        </span>
        <span
          v-if="item.type == 'objectFilter'"
          :style="scope.row[item.prop][item.showProp]"
        >
          {{ scope.row[item.prop][item.showProp] | trigger(item.filters, "label") }}
        </span>
        <span
          v-if="item.type == 'name' || !item.type"
          @click="item.type == 'name' && inlineDialog(scope.row)"
          :class="{ spamHover: item.type == 'name' }"
          >{{ scope.row[item.prop] }}</span
        >
        </el-form>
      </template>
    </el-table-column>
    <slot></slot>
  </el-table>
  <!-- <pre style="text-align: left">
      {{ tableColumns }}
    </pre>
    <hr />
    <pre style="text-align: left">
      {{ tableData }}
    </pre> -->
  <!-- </div> -->
</template>
<script>
import Sortable from "sortablejs";
import { formatTimeStrToStr } from "@/utils/formatTime";
import { getMatchRegConformValue } from "@/utils/index"
import _ from "lodash";
export default {
  name: "currenTable",
  filters: {
    formatDate(time) {
      if (time == null) {
        return '-'
      }
      return formatTimeStrToStr(time)
    },
  },
  props: {
    propsData: {
      type: Object,
      default: () => {
        return {};
      },
    },
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    tableLoading: {
      type: Boolean,
      default: false,
    },
    tableColumns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    selectionTable: {
      type: Boolean,
      default: true,
    },
    requiredRules: {
      type: Boolean,
      default: true,
    },
    searchOptions: {
      type: Object,
      default: () => {
        return {};
      },
    },
    treeProps: {
      type: Object,
      default: () => {
        return {};
      }
    },
    isShowIndex: {
      type: Boolean,
      default: false,
    },
    cellStyle: {
      type: Function,
      default: () => {
        return Function;
      }
    }
  },
  data() {
    return {
      dropCol: null,
      selectLoading: false,
      // TableSize: [],
      random: ''
    };
  },
  computed: {
    selectOptions() {
      return (val) => {
        if (val) {
          let options = this.$staticOptions[val];
          if (options) {
            return options();
          } else {
            return [];
          }
        } else {
          return false;
        }
      };
    },
    TableSize(){
      return  this.tableColumnsFilter()
    }
  },
  watch: {
    tableData: {
      handler(val, oldVal) {
        this.$nextTick(() => {
          this.$refs.multipleTable.doLayout();
          //   this.$forceUpdate()
        });
      },
      immediate: false,
    }
  },
  activated() {
    this.$refs.multipleTable.doLayout();
  },
  created() {
   
  },
  //   beforeUpdate () {
  //     this.$nextTick(() => {
  //       this.$refs.multipleTable.doLayout()
  //     })
  //   },
  mounted() {
    // this.tableColumnsFilter()
    this.random = this._uid
    // this.rowDrop()
    // this.columnDrop();
    // this.tableColumns.forEach(item => {
    //   if (item.focus) {
    //     item.focus()
    //   }
    // })
  },
  methods: {
    // type=input情况下，框实时校验
    itemOnKeyUp(item,value){
      if(item.onkeyup){
        return item.onkeyup()
      }else{
        if(value && item.validType){
          this.searchData[item.prop]=getMatchRegConformValue(item.validType,value,item.pointNumberFixed)
        }
      }
    },
    // 数字类型input框onkeyup最大最小值处理
    typeNumberOnkeyup(item,value){
      if(value){
        let _match = String(value).match(/\d+/)//正整数
        this.searchData[item.prop] = _match?_match[0]:_match
      }
      if(this.searchData[item.prop] > item.max){
        this.searchData[item.prop] = item.max
      }
      if(this.searchData[item.prop] && this.searchData[item.prop] < item.min){
        this.searchData[item.prop] = item.min
      }
      if(item.onkeyup)item.onkeyup()
    },
    tableColumnsFilter() {
      let widthSize = _.cloneDeep(this.tableColumns);
      for(let i = 0;i<widthSize.length;i++){
        let item = widthSize[i]
        if (item.type == "autocomplete" || item.type == "objectAutocomplete") {
          item.width = item.width ? item.width: "300px";
        } else if (item.type == "input" || item.type == "objectInput") {
          if (item.width == '100%') {
            item.width = ''
          } else {
            item.width = item.width ? item.width: "200px";
          }
        } else if (
          item.type == "dateTimeInput" ||
          item.type == "objectDateTimeInput"
        ) {
          item.width =item.width ? item.width:  "200px";
        } else if (item.type == "objectDateTime" || item.type == "dateTime") {
          item.width =item.width ? item.width:  "200px";
        } else if (item.width == '100%') {
          item.width = ''
        } else {
          item.width =item.width ? item.width:  "150px";
        }
      }
      // this.TableSize = widthSize;
      return widthSize
    },
    inputPlaceholder(val, item, type, func) {
      if (item.valueType) {
        if (type == "focus") {
          val.target.placeholder = "请输入" + item.label;
          if (val.target.value != "") {
            val.target.placeholder = val.target.value;
            val.target.value = "";
          }
        } else if (type == "blur") {
          //   val.target.value = "0"
          val.target.value = val.target.value.toString().replace(/[^\d.]/g,'')
          if (val.target.value == "") {
            // if (val.target.placeholder.indexOf('请输入') == -1) {
            val.target.value = val.target.placeholder;
            // }
          }
          if(item.showProp){
              func[item.prop][item.showProp]= Number(val.target.value)
            }else{
              func[item.prop]= Number(val.target.value)
            }
          // item.valueType
          //   ? (this.searchData[item.prop] = item.valueType(
          //     this.searchData[item.prop]
          //   ))
          //   : () => {
          //     return;
          //   }
        }
      }
    },
    // handeleInput (et, item) {
    //   const { optionsValue } = item
    //   let func = item.focus
    //   let filter = {
    //     logic: "And",
    //     column: optionsValue,
    //     action: "Like",
    //     value: et
    //   }
    //   debounce(func(filter), 2000,true)
    // },
    //autocomplete下拉
    querySearch(queryString, cb, val, row) {
      const { options, optionsValue, optionsLabel } = val;
      let func = val.focus;
      let data = {
        scope: row,
      };
      if (queryString) {
        data.filter = [
          {
            logic: "And",
            column: optionsValue,
            action: "Like",
            value: queryString,
          },
          // {
          //   logic: "Or",
          //   column: optionsLabel,
          //   action: "Like",
          //   value: queryString
          // }
        ];
      }
      func(data).then((res) => {
        var restaurants = this.searchOptions["options"];
        let results = queryString
          ? restaurants.filter(
              this.createFilter(queryString, optionsValue, optionsLabel)
            )
          : restaurants;
        results.forEach((key) => {
          if (typeof optionsValue === "string") {
            key.value = key[optionsValue] + "----" + key[optionsLabel];
          } else {
            key.value =
              key[optionsValue[0]][optionsValue[1]] +
              "----" +
              key[optionsLabel];
          }
        });
        // 调用 callback 返回建议列表的数据
        cb(results);
      });
    },
    createFilter(queryString, optionsValue, optionsLabel) {
      return (restaurant) => {
        if (typeof optionsValue === "string") {
          restaurant.value =
            restaurant[optionsValue] + "----" + restaurant[optionsLabel];
        } else {
          restaurant.value =
            restaurant[optionsValue[0]][optionsValue[1]] +
            "----" +
            restaurant[optionsLabel];
        }
        return (
          restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) !=
          -1
        );
      };
    },
    handleSelect(item, val, scope) {
      let data = this.tableData[scope.$index];
      if (!val.showProp) {
        if (typeof val.optionsValue === "string") {
          data[val.prop] = item[val.optionsValue];
        } else {
          data[val.prop] = item[val.optionsValue[0]][val.optionsValue[1]];
        }
      } else {
        if (typeof val.optionsValue === "string") {
          data[val.prop][val.showProp] = item[val.optionsValue];
        } else {
          data[val.prop][val.showProp] =
            item[val.optionsValue[0]][val.optionsValue[1]];
        }
      }
      this.$emit("push", item, scope, val);
    },
    // selectFocus (val, item) {
    //   this.selectLoading = true;
    //   let func = item.focus
    //   func({}).then(res => {
    //     this.selectLoading = false;
    //   })
    // },
    // dataFilter (query, item, row) {
    //   const { options, optionsValue, optionsLabel } = item
    //   let func = item.focus
    //   let data = {
    //     scope: row
    //   }
    //   this.selectLoading = true;
    //   if (query) {
    //     data.filter = {
    //       logic: "And",
    //       column: optionsLabel,
    //       action: "Like",
    //       value: query
    //     }
    //   }
    //   setTimeout(() => {
    //     func(data).then(res => {
    //       this.selectLoading = false;
    //     })
    //   }, 200);
    // },
    getMaxLength(arr) {
      return arr.reduce((acc, item) => {
        if (item) {
          const calcLen = this.getTexWidth(item);
          if (acc < calcLen) {
            acc = calcLen;
          }
        }
        return acc;
      }, 0);
    },
    getTexWidth(str) {
      let width = 0;
      const html = document.createElement("span");
      html.innerText = str;
      html.className = "getTextWidth";
      document.querySelector("body").appendChild(html);
      width = document.querySelector(".getTextWidth").offsetWidth;
      document.querySelector(".getTextWidth").remove();
      return width;
    },
    flexColumnWidth(label, prop) {
      const arr = this.tableData.map((x) => {
        if (typeof prop !== "string") {
          return x[prop[0]][prop[1]];
        } else {
          return x[prop];
        }
      });
      arr.push(label);
      return this.getMaxLength(arr) + 60 + "px";
    },
    //排序
    sortChange(data) {
      this.$emit("sortChange", data);
    },
    //点击selection框
    handleSelectionChange(val) {
      this.$emit("handleSelectionChange", val);
    },
    //点击name提交emit打开编辑页面
    inlineDialog(row) {
      this.$emit("inlineDialog", row);
    },
    //点击按钮打开自定义弹窗
    buttonClick(row, index, label) {
      this.$emit("buttonClick", row, index, label);
    },
    rowDrop() {
      const tbody = this.$refs.multipleTable.$el.querySelector(
        ".el-table__body-wrapper tbody"
      );
      const _this = this;
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0];
          _this.tableData.splice(newIndex, 0, currRow);
        },
      });
    },
    //列拖拽
    columnDrop() {
      const wrapperTr = this.$refs.multipleTable.$el.querySelector(
        ".el-table__header-wrapper tr"
      );
      let bomIndex = this.selectionTable ? 1 : 0;
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: (evt) => {
          const oldItem = this.TableSize[evt.oldIndex - bomIndex];
           this.TableSize.splice(evt.oldIndex - bomIndex, 1);
           this.TableSize.splice(evt.newIndex - bomIndex, 0, oldItem);
        },
      });
    },
  },
};
</script>
<style lang="scss" scoped>
::v-deep .el-form-item__error{
  position: relative;
}
::v-deep .el-table__fixed {
  display: block-inline !important;
  height: auto !important;
  bottom: 13px !important;
  .el-table__fixed-header-wrapper {
    z-index: auto !important;
  }
  .el-table__fixed-body-wrapper {
    z-index: auto !important;
  }
}
::v-deep .el-table__fixed::before,
.el-table__fixed-right::before {
  z-index: auto !important;
}
.spamHover {
  color: #409eff;
  cursor: pointer;
}
.spamHover:hover {
  border-bottom: 1px solid #409eff;
  color: blue;
}
span {
  white-space: pre;
}
::v-deep .el-select {
  .el-input__inner {
    padding: 0 30px 0 15px;
  }
  .el-input__prefix {
    width: 100% !important;
    left: 0;
    .el-button {
      position: absolute;
      top: 0;
      right: 0;
    }
  }
}
</style>