<template>
  <t-form
    :data="formData"
    :labelWidth="labelWidth"
    ref="form"
    @reset="onReset"
    :rules="formRules"
    @submit="onSubmit"
    scrollToFirstError="smooth"
    v-if="formData"
  >
    <t-row v-if="!expand">
      <t-col
        :span="spanC"
        v-for="item in config.slice(0, config.length >= colNum ? colNum - 1 : config.length)"
        :key="item.key"
      >
        <t-form-item v-bind="colProps" :name="item.key" :rules="item.rule">
          <template slot="label">
            <t-tooltip v-if="shouldEllipsis(item.label)" :content="item.label">
              <span>{{ sliceText(item.label) }}</span>
            </t-tooltip>
            <span v-else>{{ item.label }}</span>
          </template>
          <slot :name="item.key" :item="item" :formData="formData" v-cloak>
            <t-tooltip
              v-if="item.type === 'select'"
              :content="
                getLabelStr(
                  formData[item.key],
                  item.selectList,
                  item.labelName ? { label: item.labelName, value: item.keyName } : null,
                )
              "
              :showArrow="false"
              :overlayInnerStyle="{
                display:
                  item.multiple && !!formData[item.key] && formData[item.key].length > 0 && !item.isPopup
                    ? 'block'
                    : 'none',
              }"
            >
              <t-select
                v-bind="item.selectProps"
                v-model="formData[item.key]"
                :options="item.selectList"
                :disabled="item.disabled || false"
                :placeholder="item.placeholder || '请选择'"
                :filterable="item.filterable || false"
                :multiple="item.multiple || false"
                v-on="item.events || {}"
                :popupVisible.sync="item.isPopup"
                :clearable="item.clearable || false"
                :onChange="(value) => handleSelectChange(value, item)"
                :keys="{ label: item.labelName, value: item.keyName }"
              ></t-select>
            </t-tooltip>
            <t-date-picker
              v-else-if="item.type === 'datepicker'"
              v-model="formData[item.key]"
              :mode="item.mode || 'date'"
              :key="item.mode"
              style="width: 100%"
              :placeholder="item.placeholder || '请选择'"
              :enable-time-picker="item.enableTimePicker || false"
              :clearable="item.clearable === false ? item.clearable : item.clearable || true"
              :disabled="item.disabled || false"
              :disableDate="(date) => getDisableDate(date, item)"
              @change="(e) => (formData[item.key] = e)"
              :format="item.mode === 'quarter' ? 'YYYY-MM-DD' : ''"
              :inputProps="
                item.mode === 'quarter' && formData[item.key] !== ''
                  ? {
                      value: `${dayjs(formData[item.key]).format('YYYY')}-${
                        { 1: '一', 2: '二', 3: '三', 4: '四' }[dayjs(formData[item.key]).format('Q')]
                      }季度`,
                    }
                  : {}
              "
            />
            <t-date-range-picker
              v-else-if="item.type === 'range-datepicker'"
              range
              v-model="formData[item.key]"
              mode="date"
              style="width: 100%"
              v-bind="item.rangeDatepickerProps"
              :placeholder="item.placeholder || '请选择'"
              :clearable="item.clearable || true"
            />
            <t-date-range-picker
              v-else-if="item.type === 'daterangepicker'"
              v-model="formData[item.key]"
              allow-input
              clearable
            />
            <t-checkbox
              v-else-if="item.type === 'checkbox'"
              :disabled="item.disabled || false"
              v-model="formData[item.key]"
            ></t-checkbox>
            <t-tree-select
              v-else-if="item.type === 'tree-select'"
              style="width: 100%"
              v-bind="item.treeSelectProps"
              :data="item.selectList"
              v-model="formData[item.key]"
              :disabled="item.disabled || false"
              @remove="removeItem"
              placeholder="请选择"
              :multiple="item.multiple || false"
              :filterable="item.filterable || false"
              :minCollapsedNum="item.colNum || 0"
              :clearable="item.clearable || false"
            />
            <all-select
              v-else-if="item.type === 'all-select'"
              v-bind="item.allSelectProps"
              v-model="formData[item.key]"
              :options="item.selectList"
              :minCollapsedNum="item.colNum || 0"
              :filterable="item.filterable || false"
              :clearable="item.clearable"
              :placeholder="'请选择'"
              :allowCheckAll="item.allowCheckAll || true"
              :isSlice="item.isSlice"
              :tagProps="item.tagProps"
            />
            <t-tooltip
              :content="formData[item.key]"
              :showArrow="false"
              :overlayInnerStyle="{ display: !formData[item.key] ? 'none' : 'block' }"
              overlayClassName="colorpopup2"
              v-else
            >
              <t-input
                v-bind="item.inputProps"
                v-model="formData[item.key]"
                :placeholder="item.placeholder || '请输入'"
                :clearable="item.clearable || false"
                :disabled="item.disabled || false"
              >
                <t-icon v-if="item.iconName" :name="item.iconName" slot="suffix-icon" />
              </t-input>
            </t-tooltip>
          </slot>
        </t-form-item>
      </t-col>
      <!-- <t-col :span="spanC" v-for="i in colNum - ((config.length % colNum) + 1)" :key="i" /> -->
      <t-col :span="spanC">
        <t-form-item
          class="filter-btns"
          :class="shouldShowExtend ? 'float-right' : ''"
          labelWidth="0"
          style="display: flex; flex-direction: row; justify-content: flex-end"
        >
          <div style="margin-left: 16px">
            <t-button theme="default" variant="base" type="reset" @click="onReset">重置</t-button>
            <t-button theme="primary" type="submit">{{ submitText }}</t-button>
            <t-button v-if="shouldShowExtend" theme="primary" variant="text" @click="changeChevron">
              <span>
                {{ expand ? '收起' : '展开' }}
                <t-icon :name="expand ? 'chevron-up' : 'chevron-down'" slot="icon" />
              </span>
            </t-button>
          </div>
        </t-form-item>
      </t-col>
    </t-row>
    <t-row v-if="expand">
      <t-col :span="spanC" v-for="item in config" :key="item.key">
        <t-form-item v-bind="colProps" :name="item.key" :rules="item.rule">
          <template slot="label">
            <t-tooltip v-if="shouldEllipsis(item.label)" :content="item.label">
              <span>{{ sliceText(item.label) }}</span>
            </t-tooltip>
            <span v-else>{{ item.label }}</span>
          </template>
          <slot :name="item.key" :item="item" :formData="formData" v-cloak>
            <t-tooltip
              v-if="item.type === 'select'"
              :content="
                getLabelStr(
                  formData[item.key],
                  item.selectList,
                  item.labelName ? { label: item.labelName, value: item.keyName } : null,
                )
              "
              :showArrow="false"
              :overlayInnerStyle="{
                display:
                  item.multiple && !!formData[item.key] && formData[item.key].length > 0 && !item.isPopup
                    ? 'block'
                    : 'none',
              }"
            >
              <t-select
                v-bind="item.selectProps"
                v-model="formData[item.key]"
                :options="item.selectList"
                :disabled="item.disabled || false"
                :placeholder="item.placeholder || '请选择'"
                :filterable="item.filterable || false"
                :multiple="item.multiple || false"
                v-on="item.events || {}"
                :popupVisible.sync="item.isPopup"
                :clearable="item.clearable || false"
                :onChange="(value) => handleSelectChange(value, item)"
                :keys="{ label: item.labelName, value: item.keyName }"
              ></t-select>
            </t-tooltip>
            <t-date-picker
              v-else-if="item.type === 'datepicker'"
              v-model="formData[item.key]"
              :mode="item.mode || 'date'"
              :key="item.mode"
              style="width: 100%"
              :placeholder="item.placeholder || '请选择'"
              :enable-time-picker="item.enableTimePicker || false"
              :clearable="item.clearable === false ? item.clearable : item.clearable || true"
              :disabled="item.disabled || false"
              :disableDate="(date) => getDisableDate(date, item)"
              @change="(e) => (formData[item.key] = e)"
              :format="item.mode === 'quarter' ? 'YYYY-MM-DD' : ''"
              :inputProps="
                item.mode === 'quarter' && formData[item.key] !== ''
                  ? {
                      value: `${dayjs(formData[item.key]).format('YYYY')}-${
                        { 1: '一', 2: '二', 3: '三', 4: '四' }[dayjs(formData[item.key]).format('Q')]
                      }季度`,
                    }
                  : {}
              "
            />
            <!-- <t-date-picker -->
            <t-date-range-picker
              v-else-if="item.type === 'range-datepicker'"
              range
              v-model="formData[item.key]"
              mode="date"
              style="width: 100%"
              v-bind="item.rangeDatepickerProps"
              :placeholder="item.placeholder || '请选择'"
              :clearable="item.clearable || true"
            />
            <t-date-range-picker
              v-else-if="item.type === 'daterangepicker'"
              v-model="formData[item.key]"
              allow-input
              clearable
            />
            <t-checkbox
              v-else-if="item.type === 'checkbox'"
              :disabled="item.disabled || false"
              v-model="formData[item.key]"
            ></t-checkbox>
            <t-tree-select
              v-else-if="item.type === 'tree-select'"
              style="width: 100%"
              v-bind="item.treeSelectProps"
              :data="item.selectList"
              v-model="formData[item.key]"
              :disabled="item.disabled || false"
              @remove="removeItem"
              placeholder="请选择"
              :multiple="item.multiple || false"
              :filterable="item.filterable || false"
              :minCollapsedNum="item.colNum || 0"
              :clearable="item.clearable || false"
            />
            <all-select
              v-else-if="item.type === 'all-select'"
              v-bind="item.allSelectProps"
              v-model="formData[item.key]"
              :options="item.selectList"
              :minCollapsedNum="item.colNum || 0"
              :filterable="item.filterable || false"
              :clearable="item.clearable"
              :placeholder="'请选择'"
              :allowCheckAll="item.allowCheckAll || true"
              :isSlice="item.isSlice"
              :tagProps="item.tagProps"
            />
            <t-tooltip
              :content="formData[item.key]"
              :showArrow="false"
              :overlayInnerStyle="{ display: !formData[item.key] ? 'none' : 'block' }"
              overlayClassName="colorpopup2"
              v-else
            >
              <t-input
                v-bind="item.inputProps"
                v-model="formData[item.key]"
                :placeholder="item.placeholder || '请输入'"
                :clearable="item.clearable || false"
                :disabled="item.disabled || false"
              >
                <t-icon v-if="item.iconName" :name="item.iconName" slot="suffix-icon" />
              </t-input>
            </t-tooltip>
          </slot>
        </t-form-item>
      </t-col>
      <t-col :span="spanC" v-for="i in colNum - ((config.length % colNum) + 1)" :key="i" />
      <t-col :span="spanC">
        <t-form-item class="filter-btns" :class="shouldShowExtend ? 'float-right' : ''" labelWidth="0">
          <div style="margin-left: 16px">
            <t-button theme="default" variant="base" type="reset">重置</t-button>
            <t-button theme="primary" type="submit">{{ submitText }}</t-button>
            <t-button v-if="shouldShowExtend" theme="primary" variant="text" @click="changeChevron">
              <span>
                {{ expand ? '收起' : '展开' }}
                <t-icon :name="expand ? 'chevron-up' : 'chevron-down'" slot="icon" />
              </span>
            </t-button>
          </div>
        </t-form-item>
      </t-col>
    </t-row>
  </t-form>
</template>

<script>
// import FilterWrapper from '../filter-wrapper.vue';
import dayjs from 'dayjs';
import allSelect from '@/pages/index/components/all-select/_base.vue';
import { getLabelStr } from '@/utils/common';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';

const DOUBLE_BYTE_THRESHOLD = 255;

export default {
  INITIAL_FORM_DATA: undefined,
  components: {
    allSelect,
  },
  props: {
    labelWidth: {
      type: String,
      default: 'calc(8em + 8px)',
    },
    config: [Object, Array],
    isQuarter: {
      type: Boolean,
      default: false,
    },
    colNum: {
      type: Number,
      default: 4,
    },
    defaultExpand: {
      type: Boolean,
      default: false,
    },
    formRules: {
      type: Object,
      default: () => {},
    },
    submitText: {
      type: String,
      default: '查询',
    },
    LABEL_THRESHOLD: {
      type: Number,
      default: 7,
    },
  },
  data() {
    dayjs.extend(quarterOfYear);
    this.dayjs = dayjs;
    return {
      expand: true,
      colProps: {
        xs: 6, // >= 768
        md: 4, // >= 992px
        lg: 3, // >= 1200px
        xl: 3, // >= 1400 px
        xxl: 2, // >= 1880
      },
      isShowHighSearchButton: false,
      formData: undefined,
      formRef: null,
      inputRef: null,
    };
  },
  computed: {
    shouldShowExtend() {
      return Object.keys(this.config).length >= this.colNum;
    },
    spanC() {
      return 12 / this.colNum;
    },
  },
  watch: {
    formData: {
      deep: true,
      handler(val) {
        // 忽略首次加载
        this.$emit('formChange', val);
      },
    },
  },
  mounted() {
    this.expand = this.defaultExpand;
    this.setFormData(this.config);
    this.formRef = this.$refs.form;
    this.onReset();
    // this.formRef.reset();
    this.inputRef = this.$refs.input;
  },
  methods: {
    getLabelStr,
    handleSelectChange(value, item) {
      const { multiple, multipleAllValue, selectList } = item;

      function isEqualArr(arr1, arr2) {
        return arr1.every((values) => arr2.includes(values));
      }

      // 处理多选情况下，有全选的值
      if (multiple && typeof multipleAllValue !== 'undefined') {
        // without all value
        const allSelectValue = selectList
          .filter((itemss) => itemss.value !== multipleAllValue)
          .map((items1) => items1.value);
        console.log(allSelectValue, value, isEqualArr(allSelectValue, value));
        if (value.includes(multipleAllValue) || isEqualArr(allSelectValue, value)) {
          this.formData[item.key] = selectList.map((itemss) => itemss.value);
        }
      }
      // 增加回调方法
      this.$emit('changeSelect', value, item);
    },
    getDisableDate(date, item) {
      if (!item.relation || !item.timeRange) return false;
      const selectData = this.formData[item.relation];
      // console.log(item);
      if (item.isDisableToday) {
        const isDisable = date > new Date(dayjs().format('YYYY-MM-DD'));
        if (isDisable) return isDisable;
      }
      if (!selectData) return false;

      const formatDate = dayjs(selectData).hour(0).minute(0).second(0);
      const dayDifference = formatDate.diff(dayjs(date), 'day');
      if (item.timeRange === 'start') {
        // 大于选中结束时间的都不可选,intervalDay为number时限制全部mode模式，单位为天如intervalDay：2，intervalDay为对象如{date:1,month:1,quarter:1,year:1,},根据不同模式限制单位为天
        if (this.isNumber(item.intervalDay)) {
          return !(date <= new Date(formatDate) && dayDifference < item.intervalDay);
        }
        if (item.intervalDay && this.isNumber(item.intervalDay[item.mode])) {
          return !(date <= new Date(formatDate) && dayDifference < item.intervalDay[item.mode]);
        }
        return date > new Date(formatDate);

        // return date > new Date(formatDate);
      }

      if (item.timeRange === 'end') {
        // 小于选中开始时间的都不可选
        if (this.isNumber(item.intervalDay)) {
          return !(date >= new Date(formatDate) && dayDifference > -item.intervalDay);
        }
        if (item.intervalDay && this.isNumber(item.intervalDay[item.mode])) {
          return !(date >= new Date(formatDate) && dayDifference > -item.intervalDay[item.mode]);
        }
        return date < new Date(formatDate);
      }

      return false;
    },
    changeChevron() {
      this.expand = !this.expand;
    },
    // 计算字符串字节长度，英文字母为单字节字符，中文汉字为双字节字符
    getStringLength(str) {
      const strLength = str.length;

      let count = 0;
      for (let i = 0; i < strLength; i++) {
        count += str.charCodeAt(i) > DOUBLE_BYTE_THRESHOLD ? 2 : 1;
      }
      return count;
    },
    // 根据预设值判断label是否显示省略
    shouldEllipsis(str) {
      return this.getStringLength(str) > this.LABEL_THRESHOLD * 2;
    },
    // label文字切割
    sliceText(text, length = 7) {
      if (this.shouldEllipsis(text)) {
        return `${text.slice(0, length)}...`;
      }
      return text;
    },
    onReset() {
      this.formData = { ...this.INITIAL_FORM_DATA };
      this.$nextTick(() => {
        this.$emit('reset', true);
      });
    },
    onSubmit({ validateResult }) {
      if (validateResult === true) {
        if (this.isQuarter)
          this.config.forEach((v) => {
            if (v.type === 'datepicker') {
              v.timeRange === 'start'
                ? (this.formData[v.key] = dayjs(this.formData[v.key]).startOf(v.mode).format('YYYY-MM-DD'))
                : (this.formData[v.key] = dayjs(this.formData[v.key]).endOf(v.mode).format('YYYY-MM-DD'));
            }
          });
        console.log(this.formData, 'submit');
        this.$emit('search');
      }
    },
    setFormData(data) {
      const formData = {};
      Object.keys(data).forEach((key) => {
        const item = data[key];
        if (item) {
          formData[item.key] = item.value;
        }
      });
      this.formData = formData;

      if (!this.INITIAL_FORM_DATA) {
        this.INITIAL_FORM_DATA = { ...formData };
        // console.log('初始化数据', this.INITIAL_FORM_DATA);
      }
    },
    getParams(key) {
      if (key) return this.formData[key];
      return { ...this.formData };
    },
    setParams(formData) {
      this.formData = formData;
    },
    removeItem(value) {
      this.$emit('removeItem', value);
    },
    isNumber(value) {
      return typeof value === 'number' && !Number.isNaN(value);
    },
  },
};
</script>

<style scoped lang="less">
.float-right {
  float: right;
}
.filter-btns {
  button {
    margin-right: 10px;
    &:last-child {
      margin-right: 0;
    }
  }
}
[v-cloak] {
  display: none;
}
.t-form__item:last-of-type {
  margin-bottom: 16px !important;
}
.znsbHeadqueryDiv /deep/.t-row {
  border-bottom: 1px #eee solid;
}
</style>
