<template>
  <div class="my-filter-excel">
    <div class="my-fe-top">
      <ul class="my-fe-menu-group" v-if="tableData.sortable">
        <li class="my-fe-menu-link link-btn">
          <div class="flx">
            <el-tooltip effect="dark" :content="$t('sys.setting.asc')" placement="top" :show-after="200">
              <el-button style="padding: 8px" text @click="sortEvent('asc')">
                <template #icon>
                  <i class="iconfont iconarrow-narrow-down"></i>
                </template>
              </el-button>
            </el-tooltip>
            <el-tooltip effect="dark" :content="$t('sys.setting.desc')" placement="top" :show-after="200">
              <el-button style="padding: 8px" text @click="sortEvent('desc')">
                <template #icon>
                  <i class="iconfont iconarrow-narrow-up"></i>
                </template>
              </el-button>
            </el-tooltip>
            <el-tooltip effect="dark" :content="$t('common.table.filterClear')" placement="top" :show-after="200">
              <el-button style="padding: 8px" text @click="resetFilterEvent">
                <template #icon>
                  <i class="iconfont iconbrush-03-1"></i>
                </template>
              </el-button>
            </el-tooltip>
          </div>
        </li>
      </ul>
    </div>
    <div class="my-fe-search" v-if="ifDateFilter">
      <div class="my-fe-search-top">
        <span class="my-fe-menu-link-left-icon">
          <i v-if="!ifTimePeriod" class="iconfont iconSearch_light"></i>
          <template v-else> {{ $t("common.from") }} </template>
        </span>
        <div class="flx">
          <el-select
            v-if="!ifTimePeriod"
            v-model="tableData.option.data.fMode"
            placeholder="Select"
            :teleported="false"
            style="width: 60px; margin-right: 4px; text-align: center"
            @change="selectChangeEvent"
          >
            <el-option-group v-for="(group, index) in tableData.caseGroups" :key="index">
              <el-option v-for="item in group" :key="item.value" :label="item.label" :value="item.value" />
            </el-option-group>
          </el-select>
          <el-date-picker
            v-model="tableData.option.data.f1Val"
            :type="datePickerType"
            :format="dateFormat"
            class="filter-date-picker flx-1"
            :placeholder="$t('common.table.datePickerTips')"
          />
        </div>
      </div>
      <div class="my-fe-search-top" v-if="ifTimePeriod">
        <span class="my-fe-menu-link-left-icon"> {{ $t("common.to") }} </span>
        <el-date-picker
          v-model="tableData.option.data.f2Val"
          :type="datePickerType"
          :format="dateFormat"
          style="width: 100%"
          class="filter-date-picker"
          :placeholder="$t('common.table.datePickerTips')"
        />
      </div>
      <div class="flx-center">
        <template v-if="!ifTimePeriod">
          <el-button text :icon="Plus" class="flx-1" type="primary" size="small" @click="handleSwitchTimePerior(true)">{{
            $t("common.timePeriod")
          }}</el-button>
        </template>
        <template v-else>
          <div class="flx-1">
            <el-button text :icon="ArrowLeft" plain size="small" @click="handleSwitchTimePerior(false)"></el-button>
            <el-button-group class="ml-4" size="small">
              <el-button @click="handleChangeTimePerior('lastWeek')">
                {{ $t("business.home.saletaskMxStatistic.lastWeek") }}
              </el-button>
              <el-button @click="handleChangeTimePerior('thisWeek')">
                {{ $t("business.home.saletaskMxStatistic.thisWeek") }}
              </el-button>
              <el-button @click="handleChangeTimePerior('nextWeek')">
                {{ $t("business.home.saletaskMxStatistic.nextWeek") }}
              </el-button>
              <el-button @click="handleChangeTimePerior('thisMonth')">
                {{ $t("business.home.saletaskMxStatistic.thisMonth") }}
              </el-button>
            </el-button-group>
          </div>
        </template>
        <el-checkbox class="ml-4" v-model="ifMinute" size="small">{{ $t("common.hourMinute") }}</el-checkbox>
      </div>
    </div>
    <div class="my-fe-search" v-else>
      <div class="my-fe-search-top">
        <i class="iconfont iconSearch_light my-fe-menu-link-left-icon"></i>
        <el-select
          v-model="tableData.option.data.fMode"
          placeholder="Select"
          :teleported="false"
          style="width: 80px; margin-right: 4px; text-align: center"
          @change="selectChangeEvent"
        >
          <el-option-group v-for="(group, index) in tableData.caseGroups" :key="index">
            <el-option v-for="item in group" :key="item.value" :label="item.label" :value="item.value" />
          </el-option-group>
        </el-select>
        <el-input
          ref="filterInputRef"
          v-model="tableData.option.data.sVal"
          :placeholder="$t('common.table.searchTips')"
          clearable
          style="width: 200px"
          @focus="filterFocusEvent"
          @input="filterInputEvent"
          @keyup.enter="confirmFilterEvent"
        ></el-input>
      </div>
      <ul class="my-fe-search-list" v-if="['like', 'notlike'].includes(tableData.option.data.fMode)">
        <li class="my-fe-search-item" @click="sAllEvent">
          <template v-if="!tableData.option.data.sVal">
            <i
              class="iconfont my-fe-search-item-icon"
              :class="[
                tableData.option.data.vals.length != tableData.colValList.length ? ' iconsquare' : 'iconcheck-square-fill checked'
              ]"
            ></i>
            <span>
              {{ `${$t("common.table.selectAll")}(${tableData.colValList.length})` }}
            </span>
          </template>
          <template v-else>
            <i
              class="iconfont my-fe-search-item-icon"
              :class="[
                tableData.option.data.vals.length != searchList.length ? ' iconsquare ' : ' iconcheck-square-fill checked'
              ]"
            ></i>
            <span>
              {{ `${$t("common.table.currentlySelectAll")}(${searchList.length})` }}
            </span>
          </template>
        </li>
        <li class="my-fe-search-item" v-for="(val, sIndex) in searchList" :key="sIndex" @click="sItemEvent(val)">
          <i
            class="iconfont my-fe-search-item-icon"
            :class="[tableData.option.data.vals.indexOf(val) === -1 ? ' iconsquare ' : ' iconcheck-square-fill checked']"
          ></i>
          <span>{{ getEnumValue(val) }}</span>
        </li>
      </ul>
    </div>
    <div class="my-fe-footer flx-center">
      <el-button class="flx-1" type="primary" @click="confirmFilterEvent">{{ $t("common.table.filter") }}</el-button>
      <el-button class="flx-1" @click="resetFilterEvent">{{ $t("common.resetText") }}</el-button>
    </div>
  </div>
</template>

<script lang="ts" setup name="FilterExtend">
import { reactive, computed, watch, VNode, ref } from "vue";
import { VXETable, VxeGlobalRendererHandles } from "vxe-table";
import XEUtils from "xe-utils";
import { hasValFunc, compareInputFunc } from "../interface/index";
import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n";
import { isArray } from "@/utils/is";
import { getDefaultFilter } from "../interface";
import { Plus, ArrowLeft } from "@element-plus/icons-vue";
import dayjs from "dayjs";

interface CaseItem {
  label: string;
  value: string | number;
}

interface filterOption {
  params: any;
  sortfunc?: (scope: any) => VNode;
}

const props = withDefaults(defineProps<filterOption>(), {
  params: {}
});

const { t } = useI18n();
const filterInputRef = ref();

/**
 * @description 是否使用时分
 */
const ifMinute = ref(false);

/**
 * @description 是否开启时间段过滤
 */
const ifTimePeriod = ref(false);
const datePickerType = computed(() => {
  // let { col } = props.params;
  // let _format = col?.format ?? "YYYY-MM-DD HH:mm";
  // console.log("datePickerType col._format :>> ", _format);
  // return _format.indexOf("HH:mm") > -1 ? "datetime" : "date";
  return ifMinute.value ? "datetime" : "date";
});

const dateFormat = computed(() => {
  // let { col } = props.params;
  // let _format = col?.format ?? "YYYY-MM-DD HH:mm";

  // _format = _format.replace(/y/g, "Y").replace(/d/g, "D");
  return ifMinute.value ? "YYYY-MM-DD HH:mm" : "YYYY-MM-DD";
});

const ifDateFilter = computed(() => {
  let regExpArr = ["date$", "time$"];
  let ifMatch = false;
  let { col } = props.params;

  if (col.datatype == "datetime" || col.datatype == "date") {
    ifMatch = true;
  } else {
    for (const key of regExpArr) {
      if (key.indexOf("$") > -1 || key.indexOf("^") > -1) {
        // 正则表达式
        let reg = new RegExp(key);
        if (reg.test(col.field)) {
          ifMatch = true;
          break;
        }
      }
    }
  }
  console.log("col.field, ifMatch :>> ", col.field, ifMatch);
  return ifMatch;
});

/**
 * @description 日期筛选条件
 */
const dateCaseGroups = [
  [
    { value: "equal", label: "=" },
    { value: "ge", label: "≥" },
    { value: "le", label: "≤" }
  ]
];

/**
 * @description 默认的筛选条件
 */
const defaultCaseGroups = [
  [
    { value: "like", label: "包含" },
    { value: "notlike", label: "不包含" }
  ],
  [
    { value: "equal", label: "=" },
    { value: "ne", label: "≠" },
    { value: "greater", label: ">" },
    { value: "ge", label: "≥" },
    { value: "less", label: "<" },
    { value: "le", label: "≤" }
  ]
];
const tableData = reactive({
  option: null as any,
  colValList: [] as string[],
  caseGroups: [] as CaseItem[][],
  sortable: false
});

const getEnumValue = (val: any) => {
  let msg = val;
  // console.log("getEnumValue props.params.enum, props.params :>> ", props.params.enum, props.params);
  if (props.params.hasOwnProperty("enum") && isArray(props.params.enum) && props.params.enum.length) {
    let itm =
      props.params.enum.find((item: CaseItem) => {
        let _val = isNaN(Number(val)) ? val : Number(val);
        let itmVal = isNaN(Number(item.value)) ? item.value : Number(item.value);
        return _val === itmVal;
      }) || {};
    msg = itm.label || val;
  } else if (props.params.col?.datatype == "checkbox") {
    msg = Boolean(Number(val)) ? t("sys.setting.yes") : t("sys.setting.no");
  }
  return msg;
};

const searchList = computed(() => {
  const { option, colValList } = tableData;
  if (option) {
    return option.data.sVal ? colValList.filter(val => compareInputFunc(val, option.data.sVal, option.data.fMode)) : colValList;
  }
  return [];
});

const load = () => {
  const { params } = props;
  if (params) {
    const { $table, column, col } = params;
    const { fullData } = $table.getTableData();
    console.log("FilterExtend $table :>> ", $table);
    console.log("FilterExtend $table getCheckedFilters :>> ", $table.getCheckedFilters());
    const option = column.filters[0];
    const colValList = Object.keys(XEUtils.groupBy(fullData, column.field));
    let _default = getDefaultFilter(col)[0].data;
    console.log("option :>> ", option);
    tableData.option = option;
    tableData.option.data = tableData.option.data ?? _default;
    tableData.colValList = colValList;
    tableData.sortable = column.sortable ?? false;
    tableData.caseGroups = ifDateFilter.value ? dateCaseGroups : defaultCaseGroups;

    if (option.data.f1Val && option.data.f2Val) {
      ifTimePeriod.value = true;
    }
    console.log("tableData.option.data :>> ", tableData.option.data);
  }
};

/**
 * @description 点击全选
 */
const sAllEvent = () => {
  const { option } = tableData;
  if (option) {
    const { data } = option;
    if (data.vals.length > 0) {
      data.vals = [];
    } else {
      if (data.sVal) {
        // 正在搜索
        data.vals = tableData.colValList.filter(val => compareInputFunc(val, data.sVal, data.fMode));
      } else {
        // 没有搜索
        data.vals = tableData.colValList;
      }
    }
  }
};

const sItemEvent = (val: string) => {
  const { option } = tableData;
  if (option) {
    const { data } = option;
    const vIndex = data.vals.indexOf(val);
    if (vIndex === -1) {
      data.vals.push(val);
    } else {
      data.vals.splice(vIndex, 1);
    }
  }
};

/**
 * @description 确认按钮
 */
const confirmFilterEvent = () => {
  const { params } = props;
  const { option } = tableData;
  if (params && option) {
    const { data } = option;
    const { $panel } = params;
    data.f1 = "";
    data.f2 = "";
    if (ifDateFilter.value) {
      data.f1Val = dayjs(data.f1Val).format(dateFormat.value);
      data.f2Val && (data.f2Val = dayjs(data.f2Val).format(dateFormat.value));
    } else {
      if (!["like", "notlike"].includes(data.fMode)) {
        data.f1Val = data.sVal;
        data.vals = [];
      }
    }
    let _option = option;
    ifDateFilter.value && (_option.format = dateFormat.value);
    $panel.changeOption(null, true, _option);
    $panel.confirmFilter();
  }
};

const filterInputEvent = (val: any) => {
  const { params } = props;
  const { option } = tableData;
  if (params && option) {
    const { data } = option;

    data.f1 = "";
    data.f2 = "";
    if (!["like", "notlike"].includes(data.fMode)) {
      data.f1Val = data.sVal;
      data.vals = [];
    } else {
      data.vals = tableData.colValList.filter(val => compareInputFunc(val, data.sVal, data.fMode));
    }
  }
};

const filterFocusEvent = (ev: any) => {
  filterInputRef.value.select();
};

/**
 * @description 快捷选择日期
 * @param type DatePricker类型
 */
const handleChangeTimePerior = (type: string) => {
  let _start = "";
  let _end = "";
  let _format = dateFormat.value;

  switch (type) {
    case "lastWeek":
      _start = dayjs().subtract(1, "week").startOf("week").format(_format);
      _end = dayjs().subtract(1, "week").endOf("week").format(_format);
      break;
    case "thisWeek":
      _start = dayjs().subtract(0, "week").startOf("week").format(_format);
      _end = dayjs().subtract(0, "week").endOf("week").format(_format);
      break;
    case "nextWeek":
      _start = dayjs().subtract(-1, "week").startOf("week").format(_format);
      _end = dayjs().subtract(-1, "week").endOf("week").format(_format);
      break;
    case "thisMonth":
      _start = dayjs().subtract(0, "month").startOf("month").format(_format);
      _end = dayjs().subtract(0, "month").endOf("month").format(_format);
      break;
  }
  tableData.option.data.f1Val = _start;
  tableData.option.data.f2Val = _end;
};

/**
 * @description 切换时间区间
 * @param bool
 */
const handleSwitchTimePerior = (bool: boolean) => {
  if (bool) {
    tableData.option.data.f1Type = "ge";
    tableData.option.data.f2Type = "le";
  } else {
    tableData.option.data.f2Val = "";
    tableData.option.data.f2Type = "";
  }
  ifTimePeriod.value = bool;
};

/**
 * 重置or 清空
 * @param isAll 是否清空全部
 */
const resetFilterEvent = () => {
  const { params } = props;
  if (params) {
    const { $panel } = params;
    $panel.resetFilter();
  }
};

const childMenuClickEvent = (cItem: CaseItem) => {
  VXETable.modal.alert({ content: cItem.label });
};

/**
 * 升序,降序
 * @param order 顺序
 */
const sortEvent = (order: "desc" | "asc" | null) => {
  const { params, sortfunc } = props;
  if (params) {
    const { $table, $panel, column } = params;
    $table.sort(column.field, order);
    $panel.confirmFilter();

    sortfunc && sortfunc({ sortList: $table.getSortColumns() });
  }
};

/**
 * @description 下拉选择
 */
const selectChangeEvent = (val: any) => {
  tableData.option.data.fMode = val;
};

watch(
  () => props.params,
  (val: any, oldVal: any) => {
    if (!oldVal) return load();
    if (val.$columnIndex != oldVal.$columnIndex) {
      load();
    }
  },
  { immediate: true }
);

defineExpose({
  tableData,
  searchList,
  sAllEvent,
  sItemEvent,
  confirmFilterEvent,
  resetFilterEvent,
  childMenuClickEvent
});
</script>

<style lang="scss">
.my-filter-excel {
  user-select: none;

  ul,
  li {
    list-style: none;
  }

  .my-fe-menu-link {
    position: relative;
    padding-left: 30px;
    padding-right: 20px;
    cursor: pointer;
    line-height: 36px;

    &:not(.link-btn):hover {
      background-color: $color-gray-3;
    }

    &.link-btn {
      cursor: default;
      padding-top: 4px;
      padding-bottom: 3px;
      // display: flex;
      // align-items: center;

      .el-button + .el-button {
        margin-left: 4px;
      }
    }
  }
  .my-fe-menu-link-left-icon {
    position: absolute;
    left: 10px;
    top: 0;
    bottom: 0;
    margin: auto;
  }
  .my-fe-menu-link-right-icon {
    position: absolute;
    right: 10px;
    top: 0;
    bottom: 0;
    margin: auto;
  }
  .my-fe-search {
    padding: 0 20px 0 30px;
  }
  .my-fe-search-top {
    position: relative;
    padding: 5px 0;

    .my-fe-menu-link-left-icon {
      left: -20px;
      height: 14px;
    }
  }
  .my-fe-search-list {
    margin: 0;
    border: 1px solid $color-gray-5;
    padding: 2px 10px;
    overflow: auto;
    height: 140px;
    border-radius: $br-sm;

    .my-fe-search-item {
      cursor: pointer;
      padding: 2px 0;

      .iconfont {
        margin-right: 2px;
        width: 16px;
      }
      .checked {
        color: var(--lj-color-primary-500);
      }
    }
  }
  .filter-date-picker {
    position: relative;
    display: flex;
    .el-input__wrapper {
      flex: 1;
    }
  }
}

.my-filter-excel .my-fe-top .my-fe-menu-group {
  position: relative;
  margin: 0;
  padding: 0;
}
.my-filter-excel .my-fe-top .my-fe-menu-group:after {
  content: "";
  position: absolute;
  left: 30px;
  right: 20px;
  bottom: 0;
  border-bottom: 1px solid #e2e4e7;
}
// .my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link {
//   position: relative;
//   padding: 4px 20px 4px 30px;
//   cursor: pointer;
// }
// .my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link:hover {
//   background-color: #c5c5c5;
// }
// .my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link-left-icon {
//   position: absolute;
//   left: 10px;
//   // top: 6px;
//   top: 0;
//   bottom: 0;
//   margin: auto;
//   // height: 13px;
// }
// .my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link-right-icon {
//   position: absolute;
//   right: 10px;
//   top: 6px;
// }
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link:hover .my-fe-menu-child-list {
  display: block;
}
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-menu-child-list {
  display: none;
  position: absolute;
  top: 0;
  right: -120px;
  width: 120px;
  background-color: #fff;
  border: 1px solid #dadce0;
  box-shadow: 3px 3px 4px -2px rgba(0, 0, 0, 0.6);
}
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list {
  position: relative;
  padding: 0;
}
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list:after {
  content: "";
  position: absolute;
  width: 90px;
  right: 0;
  bottom: 0;
  border-bottom: 1px solid #e2e4e7;
}
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list > .my-fe-child-menu-item {
  position: relative;
  padding: 4px 20px 4px 30px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list > .my-fe-child-menu-item:hover {
  background-color: #c5c5c5;
}
// .my-filter-excel .my-fe-search .my-fe-search-list {
//   padding: 0 10px 0 30px;
// }
// .my-filter-excel .my-fe-search .my-fe-search-top {
//   position: relative;
//   padding: 5px 0;
// }
// .my-filter-excel .my-fe-search .my-fe-search-top > input {
//   border: 1px solid #ababab;
//   padding: 0 20px 0 2px;
//   width: 200px;
//   height: 22px;
//   line-height: 22px;
// }
// .my-filter-excel .my-fe-search .my-fe-search-top > .my-fe-search-icon {
//   position: absolute;
//   right: 5px;
//   top: 10px;
// }
// .my-filter-excel .my-fe-search .my-fe-search-list {
//   margin: 0 20px 0 30px;
//   border: 1px solid $color-gray-5;
//   padding: 2px 10px;
//   overflow: auto;
//   height: 140px;
//   border-radius: $br-sm;
// }
// .my-filter-excel .my-fe-search .my-fe-search-list .my-fe-search-item {
//   cursor: pointer;
//   padding: 2px 0;
// }
// .my-filter-excel .my-fe-search .my-fe-search-list .my-fe-search-item .my-fe-search-item-icon {
//   width: 16px;
// }
.my-filter-excel .my-fe-footer {
  text-align: right;
  padding: 10px 20px 10px 30px;
}
.my-fe-popup .my-fe-popup-filter {
  padding-left: 30px;
}
.my-fe-popup .my-fe-popup-filter > .my-fe-popup-filter-select {
  width: 120px;
}
.my-fe-popup .my-fe-popup-filter > .my-fe-popup-filter-input {
  margin-left: 15px;
  width: 380px;
}
.my-fe-popup .my-fe-popup-describe {
  padding: 20px 0 10px 0;
}
.my-fe-popup .my-fe-popup-concat {
  padding-left: 50px;
}
.my-fe-popup .my-fe-popup-footer {
  text-align: right;
}
</style>
