<!-- eslint-disable vue/v-on-event-hyphenation -->
<template>
  <div ref="divComInputFilter">
    <a-input
      ref="aComInputFilter"
      v-if="!ifTextarea"
      AutoComplete="off"
      :autofocus="autofocus"
      v-model:value="filterValue"
      @keydown="onKeyDownDelete"
      @keyup="onKeyUpDelete"
      @pressEnter="pressEnter"
      @focus="foucus" />
    <a-textarea
      ref="aComInputFilter"
      class="input-textarea-span"
      v-else
      AutoComplete="off"
      :autofocus="autofocus"
      v-model:value="filterValue"
      @keydown="onKeyDownDelete"
      @keyup="onKeyUpDelete"
      @pressEnter="pressEnter"
      @focus="foucus" />
    <span style="position: absolute; top: -9999px; left: 0px; white-space: pre; font-size: 12px">
      >
      {{ filterValue }}
    </span>
    <!-- 多选选项 -->
    <div v-if="isOptionsShow" class="show-options-content">
      <div class="ns-input-filter-list" v-if="multiSearchOptions.length > 0">
        <ul class="options-list-text" ref="showOptionsContent">
          <p v-if="emptyLength > 0" class="is-disabled"> 是否是空值 </p>
          <li
            @click.stop="chooseOption(item, index)"
            v-for="(item, index) in multiSearchOptions"
            :key="index"
            :style="index < emptyLength ? '' : 'display:none'">
            <div class="check-label">
              <a-checkbox
                v-model:checked="item.checked"
                :disabled="item.disabled"
                class="check-label-checked" />
              <span class="check-label-text">
                {{ item.label }}
              </span>
            </div>
          </li>
          <p v-if="emptyLength > 0" class="is-disabled"> 按值筛选 </p>
          <li
            @click.stop="chooseOption(item, index)"
            v-for="(item, index) in multiSearchOptions"
            :key="index"
            :style="index >= emptyLength ? '' : 'display:none'">
            <div class="check-label">
              <a-checkbox
                v-model:checked="item.checked"
                :disabled="item.disabled"
                class="check-label-checked" />
              <span class="check-label-text">
                {{ item.label }}
              </span>
            </div>
          </li>
        </ul>
        <div class="options-list-footer">
          <a-button
            type="primary"
            class="footer-submit-button"
            :disabled="isCanSubmit"
            @click.stop="submit"
            >确定</a-button
          >
          <a-button class="footer-canel-button" @click.stop="canel">取消</a-button>
        </div>
      </div>
      <div class="ns-input-filter-list" v-else>
        <ul class="options-list-text">
          <p class="is-disabled"> 暂无数据 </p>
        </ul>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import {
    defineComponent,
    ref,
    computed,
    toRaw,
    onMounted,
    nextTick,
    onBeforeUnmount,
    watch,
  } from 'vue';
  import { onClickOutside } from '@vueuse/core';
  import { http } from '/nerv-lib/util';
  import * as utils from './input-filter-util';

  export default defineComponent({
    name: 'NsInputFilterMultiSearch',
    props: {
      value: String,
      chooseItem: {
        type: Object,
        default: () => {},
      },
      spanIndex: Number,
      autofocus: Boolean,
      optionsValue: {
        type: Array,
        default: () => [],
      },
    },
    emits: ['change', 'chooseOptions', 'keydown', 'canel', 'pressEnter'],
    setup(props, ctx) {
      // console.log('NsInputFilterMultiSearch');
      // console.log(props);
      const focusObj = ref({
        focus: true,
      });
      const emptyLength = ref(0);

      //span点击 input为textArea
      // const ifTextarea = ref(typeof props.spanIndex != 'undefined' ? true : false);
      const ifTextarea = ref(false);
      const showOptionsContent = ref();
      const aComInputFilter = ref(null);

      onMounted(() => {
        if (props.autofocus) {
          aComInputFilter.value != null
            ? aComInputFilter.value.input.focus({
                cursor: 'start', // 聚焦在文本的开始位置
              })
            : '';
        }
      });
      const multiSearchOptions = ref([Object]);

      const isOptionsShow = ref(false);

      let isEmptyItem = ref(props.chooseItem);
      let filterValue = ref(toRaw(props.value));
      const arrayLength = ref(0);
      const optionInfo = ref();
      const page = ref(0);

      const checkedOptions = ref(
        typeof props.optionsValue != 'undefined'
          ? JSON.parse(JSON.stringify(props.optionsValue))
          : [],
      );

      let isCanSubmit = computed(() => {
        let arry = multiSearchOptions.value.filter(function (item) {
          return item.checked == true;
        });
        if (arry.length <= 0 && multiSearchOptions.value.length > 0) {
          multiSearchOptions.value[0].value == 'empty'
            ? (multiSearchOptions.value[0].disabled = false)
            : '';
        }
        return arry.length > 0 ? false : true;
      });

      initOptions();
      function initOptions() {
        multiSearchOptions.value = [];
        isPushEmpty();
        if (
          typeof props.chooseItem.item.componentProps.interfaceGet == 'undefined' ||
          !props.chooseItem.item.componentProps.interfaceGet
        ) {
          arrayLength.value += props.chooseItem.item.componentProps.options.length;
          multiSearchOptions.value = multiSearchOptions.value.concat(
            props.chooseItem.item.componentProps.options,
          );
          pushChecked();
        } else {
          // multiSearchOptions.value.unshift({
          //   label: '全选',
          //   value: 'allChoose',
          // });
          interfaceGetOptions();
        }
      }

      function pushChecked() {
        // multiSearchOptions.value.splice(emptyLength.value, 1, {
        //   label: '全选',
        //   value: 'allChoose',
        // });
        // multiSearchOptions.value.unshift();
        multiSearchOptions.value.forEach((elem) => {
          elem.checked = false;
        });
        pushCheckedOption();
        isOptionsShow.value = true;
      }

      function isPushEmpty() {
        if (isEmptyItem.value.showEmptyOption.length > 0) {
          emptyLength.value = isEmptyItem.value.showEmptyOption.length;
          multiSearchOptions.value = JSON.parse(JSON.stringify(isEmptyItem.value.showEmptyOption));
          let notEmpty = isEmptyItem.value.showEmptyOption.filter(function (arr: {
            value: string;
          }) {
            return arr.value == 'notEmpty';
          });
          if (notEmpty.length > 0) {
            arrayLength.value = 1;
          }
        }
      }

      /**
       * 接口获取数据
       */
      function interfaceGetOptions() {
        const requestMethod = props.chooseItem.item.componentProps.requestMethod;
        const params =
          typeof props.chooseItem.item.componentProps.params != 'undefined'
            ? props.chooseItem.item.componentProps.params
            : {};
        const api =
          typeof props.chooseItem.item.componentProps.api != 'undefined'
            ? props.chooseItem.item.componentProps.api
            : '';
        const config = {
          // headers: {
          //   'Content-Type': 'multipart/form-data',
          // },
        };
        const path = props.chooseItem.item.componentProps.labelFieldPath.split('[*]')[0].slice(1);
        const labelField = props.chooseItem.item.componentProps.labelFieldPath
          .split('[*]')[1]
          .slice(1);
        const value = props.chooseItem.item.componentProps.valueFieldPath.split('[*]')[1].slice(1);
        const method = requestMethod;
        let info = {
          params,
          api,
          config,
          path,
          labelField,
          value,
          method,
        };
        optionInfo.value = info;
        handleParams();
        switch (requestMethod) {
          case 'GET':
            optionInfo.value.method = 'get';
            break;
          case 'POST':
            optionInfo.value.method = 'post';
            break;
          default:
            break;
        }
        interfaceHttp(undefined).then(
          (value) => {
            handleScroll();
          },
          (reason) => {
            // console.log(reason);
          },
        );
      }

      /**
       * 处理参数
       */
      function handleParams() {
        let api = optionInfo.value.api;
        if (api.indexOf('http') != -1) {
          let i = 1;
          while (i <= 4) {
            let delIndex = api.indexOf('/');
            api = api.slice(delIndex == 0 ? delIndex + 1 : delIndex);
            i++;
          }
          optionInfo.value.api = api;
        }
      }

      //是否需要分页
      const isPaging = ref(true);

      /**
       *
       */
      function interfaceHttp(params: undefined | Object) {
        return new Promise(function (resolve, reject) {
          typeof showOptionsContent.value != 'undefined'
            ? showOptionsContent.value.removeEventListener('scroll', () => {})
            : '';
          let api = optionInfo.value.api;
          optionInfo.value.page = page.value;
          if (typeof params != 'undefined') {
            //optionInfo.value.page = page.value;
            api = optionInfo.value.api;
          }
          http[optionInfo.value.method](
            api,
            {
              // optionInfo.value.params
              page: optionInfo.value.page,
            },
            optionInfo.value.config,
          )
            .then((res: { [x: string]: any[] }) => {
              arrayLength.value += res.totalCount;
              if (
                res[optionInfo.value.path].length > 0 &&
                (typeof res.page != 'undefined' ? res.page == page.value : true)
              ) {
                typeof res.page == 'undefined' ? (isPaging.value = false) : '';
                res[optionInfo.value.path].forEach((elem: { [x: string]: any }) => {
                  let item = {
                    value: elem[optionInfo.value.value],
                    label: elem[optionInfo.value.labelField],
                  };
                  multiSearchOptions.value.push(item);
                });
                if (typeof params != 'undefined') {
                  pushCheckedOption();
                } else {
                  pushChecked();
                }
              } else if (page.value > 0) {
                page.value--;
              }
              isOptionsShow.value = true;
              resolve('success');
            })
            .catch((err: any) => {
              reject('fail');
              isOptionsShow.value = true;
            });
        });
      }

      function pushCheckedOption() {
        checkedOptions.value.length > 0 ? '' : (checkedOptions.value = []);
        if (
          typeof props.value != 'undefined' &&
          props.value.indexOf('空') != -1 &&
          props.value.indexOf('不为空') == -1
        ) {
          checkedOptions.value.push('empty');
          multiSearchOptions.value.forEach((elem) => {
            checkedOptions.value.forEach((item: any) => {
              elem.value == item ? (elem.checked = true) : (elem.disabled = true);
            });
          });
          return;
        }
        if (typeof props.value != 'undefined' && props.value.indexOf('不为空') != -1) {
          checkedOptions.value.push('notEmpty');
        }
        // console.log(checkedOptions.value.length);
        // if(checkedOptions.value.length)
        multiSearchOptions.value.forEach((elem) => {
          checkedOptions.value.forEach((item: any) => {
            elem.value == item ? (elem.checked = true) : '';
          });
        });
        //有其他选项场景把空选项禁用
        let ifHaveAllChose = checkedOptions.value.filter(function (elem) {
          return elem != 'empty';
        });
        if (ifHaveAllChose.length > 0) {
          multiSearchOptions.value[0].value == 'empty'
            ? (multiSearchOptions.value[0].disabled = true)
            : '';
        }
      }

      let inputWidth = computed(() => {
        if (typeof filterValue.value == 'undefined') {
          return 8 + 'px';
        }
        return DataLength(filterValue.value) + 'px';
      });

      //计算字符长度
      const DataLength = (fData: string) => {
        return utils.DataLength(fData);
      };

      const divLeft = ref();
      divLeft.value =
        DataLength(typeof props.value != 'undefined' ? props.value.split('：')[0] : '') + 'px';

      //回车
      function pressEnter() {
        if (
          props.value.split('：')[0] == filterValue.value.split('：')[0] &&
          filterValue.value.indexOf('：') != -1
        ) {
          if (!isCanSubmit.value) {
            submit();
          } else {
            filterValue.value = filterValue.value.split('：')[0] + '：';
            isOptionsShow.value = true;
          }
          return;
        }
        ctx.emit('pressEnter', filterValue.value, props.spanIndex, true, true);
      }

      //删除
      function onKeyDownDelete(event: { key: string }) {
        if (event.key == 'Backspace') {
          if (typeof filterValue.value != 'undefined' && filterValue.value != '') {
            return;
          }
          ctx.emit('keydown', props.spanIndex);
        }
      }

      function onKeyUpDelete(event: { key: string }) {
        if (event.key == 'Backspace') {
          if (typeof filterValue.value != 'undefined' && filterValue.value != '') {
            if (filterValue.value.indexOf('：') != -1) {
              let value = filterValue.value.split('：')[1];
              let labelArray = value.split('|');
              multiSearchOptions.value.forEach((elem) => {
                elem.checked = false;
                labelArray.forEach((item) => {
                  elem.label == item ? (elem.checked = true) : '';
                });
              });
              let ifChooseArray = multiSearchOptions.value.filter(function (elem) {
                return elem.checked == true;
              });
              if (ifChooseArray.length <= 0) {
                multiSearchOptions.value.forEach((elem) => {
                  elem.disabled = false;
                });
              }
            } else {
              isOptionsShow.value = false;
            }
            return;
          }
        }
      }

      /**
       * 空值与不为空值选中
       */
      function chooseOption(item, index: number) {
        if (item.disabled) return;
        multiSearchOptions.value[index].checked = !item.checked;
        if (!item.checked) {
          checkedOptions.value.forEach((elem: string, elemIndex: any) => {
            if (elem == item.value) {
              checkedOptions.value.splice(elemIndex, 1);
            }
          });
        }
        if (item.value == 'empty') {
          multiSearchOptions.value.forEach((elem, keyIndex) => {
            if (keyIndex != index) {
              keyIndex != 0 ? (elem.checked = false) : '';
              elem.disabled = item.checked;
            }
          });
        } else if (item.value == 'allChoose') {
          // multiSearchOptions.value.forEach((elem, keyIndex) => {
          //   if (elem.value == 'empty') {
          //     elem.checked = false;
          //     elem.disabled = item.checked;
          //   } else {
          //     elem.checked = item.checked;
          //     elem.disabled = false;
          //   }
          // });
        } else {
          // multiSearchOptions.value[0].checked = false;
          // multiSearchOptions.value.forEach((elem, keyIndex) => {
          //   if (elem.value == 'empty') {
          //     elem.checked = false;
          //     elem.disabled = item.checked;
          //   } else {
          //     elem.checked = item.checked;
          //     elem.disabled = false;
          //   }
          // });
        }
        // //判断全选中
        // let chooseArray = multiSearchOptions.value.filter(function (arr) {
        //   return arr.checked == true;
        // });
        // console.log('chooseArray.length');
        // console.log(chooseArray.length);
        // console.log(arrayLength.value);
        // console.log(emptyLength.value);
        // if (chooseArray.length == arrayLength.value) {
        //   multiSearchOptions.value[emptyLength.value].checked = true;
        // }
        // filterValue.value = filterValue.value.split('：')[0] + '：';
        // let flag = 0;
        // multiSearchOptions.value.forEach((item) => {
        //   if (item.checked) {
        //     if (flag != 0) {
        //       filterValue.value += '|' + item.label;
        //     } else {
        //       filterValue.value += item.label;
        //     }
        //     flag += 1;
        //   }
        // });
      }

      /**
       * 确定
       */
      function submit() {
        let chooseArray = multiSearchOptions.value.filter(function (elem) {
          return elem.checked == true;
        });
        let filterArrayShowValue = '';
        let filterArrayEmit = {
          value: [],
        };
        chooseArray.forEach((elem, index) => {
          elem.label != '全选' ? (filterArrayShowValue += elem.label) : '';
          index != chooseArray.length - 1 && elem.label != '全选'
            ? (filterArrayShowValue += '|')
            : '';
          if (elem.value != 'empty' && elem.value != 'notEmpty') {
            // if (elem.value == 'allChoose') {
            //   return;
            // }
            filterArrayEmit.value.push(elem.value);
          } else {
            filterArrayEmit[elem.value] = true;
            elem.value == 'empty' ? delete filterArrayEmit.value : '';
          }
        });
        let spanIndex = typeof props.spanIndex != 'undefined' ? props.spanIndex : -1;
        isOptionsShow.value = false;
        ctx.emit(
          'chooseOptions',
          filterValue.value,
          filterArrayShowValue,
          filterArrayEmit,
          spanIndex,
        );
      }

      /**
       * 取消
       */
      function canel() {
        isOptionsShow.value = false;
        ctx.emit('canel', typeof props.spanIndex != 'undefined' ? props.spanIndex : -1);
      }

      //需要监听的数据
      watch(
        () => filterValue.value,
        (newValue: any, oldValue) => {
          let spanIndex = typeof props.spanIndex != 'undefined' ? props.spanIndex : -1;
          ctx.emit('change', newValue, spanIndex);
          if (newValue.indexOf('：') != -1) {
            // let label = newValue.split('：')[0];
            let valueArray =
              newValue.split('：')[1].indexOf('|') != -1
                ? newValue.split('：')[1].split('|')
                : [newValue.split('：')[1]];
            valueArray.length > 0 ? inputCheckedChoose(valueArray) : '';
          }
        },
      );

      //根据filterValue值自动选中
      function inputCheckedChoose(valueArray: any[]) {
        let chooseIndex: number[] = [];
        let unChooseIndex: number[] = [];
        valueArray.forEach((valueItem: any) => {
          let flag = -1;
          let filter = multiSearchOptions.value.filter(function (elem) {
            flag += 1;
            if (elem.label == valueItem) {
              chooseIndex.push(flag);
            }
            return elem.label == valueItem;
          });
        });
        for (let index = 0; index < multiSearchOptions.value.length; index++) {
          unChooseIndex.push(index);
        }
        unChooseIndex = differenceBy(chooseIndex, unChooseIndex);
        chooseIndex.length > 0
          ? chooseIndex.forEach((chItem) => {
              !multiSearchOptions.value[chItem].disabled
                ? (multiSearchOptions.value[chItem].checked = true)
                : '';
            })
          : '';
        unChooseIndex.length > 0
          ? unChooseIndex.forEach((chItem) => {
              multiSearchOptions.value[chItem].checked = false;
            })
          : '';
      }

      //二次过滤
      const differenceBy = (array1: string | any[], array2: string | any[]) => {
        var result = [];
        for (var i = 0; i < array2.length; i++) {
          var obj = array2[i];
          var num = obj;
          var isExist = false;
          if (num && num !== 0) {
            for (var j = 0; j < array1.length; j++) {
              var aj = array1[j];
              var n = aj;
              if (n === num) {
                isExist = true;
                break;
              }
            }
            if (!isExist) {
              result.push(obj);
            }
          }
        }
        return result;
      };

      function foucus() {
        if (multiSearchOptions.value.length <= 0) return;
        isOptionsShow.value = true;
      }

      function checkDefault() {
        if (props.value.indexOf('：') != -1) {
          let valueArray =
            props.value.split('：')[1].indexOf('|') != -1
              ? props.value.split('：')[1].split('|')
              : [props.value.split('：')[1]];
          valueArray.length > 0 ? inputCheckedChoose(valueArray) : '';
        }
        pressEnter();
      }

      const divComInputFilter = ref(null);
      /**
       * 选中div区域外
       */
      onClickOutside(divComInputFilter, () => {
        isOptionsShow.value = false;
      });

      //监听滚动代码区域 showOptionsContent
      let oldScrollTop = 0; // 记录上一次滚动结束后的滚动距离
      const scrollTop = ref<number>(0); // 记录当前的滚动距离
      const scrollFixedStatus = ref<boolean>(true);
      function handleScroll() {
        nextTick(() => {
          showOptionsContent.value.addEventListener('scroll', () => {
            //获取dom滚动距离
            scrollTop.value = showOptionsContent.value.scrollTop;

            //获取可视区高度
            const offsetHeight = showOptionsContent.value.offsetHeight;

            //获取滚动条总高度
            const scrollHeight = showOptionsContent.value.scrollHeight;

            //console.log('scrollTop.value', scrollTop.value, scrollHeight, offsetHeight);

            if (scrollTop.value + offsetHeight >= scrollHeight) {
              // 把距离顶部的距离加上可视区域的高度 等于或者大于滚动条的总高度就是到达底部
              // console.log('已滚动到底部');
              if (isPaging.value) {
                page.value++;
                interfaceHttp('bottom');
              }
            }
          });
        });
      }
      onBeforeUnmount(() => {
        if (typeof showOptionsContent.value != 'undefined' && showOptionsContent.value != null) {
          showOptionsContent.value.removeEventListener('scroll', () => {}); // 离开当前组件别忘记移除事件监听
        }
      });

      watch(
        () => scrollTop.value,

        (newValue, oldValue) => {
          setTimeout(() => {
            if (newValue === window.scrollY) {
              // 延时执行后当newValue等于window.scrollY，代表滚动结束
              // console.log('滚动结束');
              oldScrollTop = newValue; // 每次滚动结束后都要给oldScrollTop赋值
              // scrollFixedStatus.value = true;
            }
          }, 20); // 必须使用延时器，否则每次newValue和window.scrollY都相等，无法判断，20ms刚好大于watch的侦听周期，故延时20ms
          if (oldScrollTop === oldValue) {
            scrollFixedStatus.value = false;
            // 每次滚动开始时oldScrollTop与oldValue相等
            // console.log('滚动开始');
          }
        },
      );

      return {
        divComInputFilter,
        foucus,
        inputWidth,
        isCanSubmit,
        divLeft,
        filterValue,
        focusObj,
        isEmptyItem,
        aComInputFilter,
        multiSearchOptions,
        isOptionsShow,
        ifTextarea,
        emptyLength,
        pressEnter,
        onKeyUpDelete,
        onKeyDownDelete,
        chooseOption,
        submit,
        canel,
        showOptionsContent,
        checkDefault,
      };
    },
  });
</script>
<style lang="less" scoped>
  .ant-input:focus {
    border: transparent !important;
    box-shadow: none !important;
  }
  .show-options-content {
    position: absolute;
    z-index: 9;
    left: v-bind(divLeft);
  }
  .ns-input-filter-list {
    border-radius: 0;
    background-color: #fff;
    box-shadow: 0 0 16px 0 rgb(54 58 80 / 16%);
    min-width: 150px;
    color: rgba(0, 0, 0, 0.9);
  }
  .options-list-footer {
    margin: 0 10px;
    border-top: 1px solid #e7eaef;
    padding: 10px 0;
    white-space: nowrap;

    .footer-submit-button {
      width: 60px;
      margin-right: 10px;
    }
    .footer-canel-button {
      width: 60px;
    }
  }
  .options-list-text {
    overflow-y: auto;
    padding: 0;
    list-style: none;
    color: rgba(0, 0, 0, 0.9);
    margin: 0px;
    max-height: 180px;

    .check-label {
      position: relative;
      vertical-align: middle;
      padding-left: 20px;
      margin-top: 0;
      margin-right: 18px;
      min-height: 18px;
      color: rgba(0, 0, 0, 0.9);

      :deep(.ant-checkbox-wrapper) {
        display: inline-flex !important;
      }

      .check-label-checked {
        position: absolute;
        top: 0;
        left: 0;
      }
    }
    .check-label-text {
      line-height: 20px;
      cursor: pointer;
      font-size: 12px;
    }
  }
  .is-disabled {
    background-color: transparent;
    color: rgba(0, 0, 0, 0.25);
    cursor: not-allowed;
    font-size: 12px;
    margin-bottom: 0px;
    padding: 6px 10px;
  }
  // .options-list-text > li
  .options-list-text > li:first-child,
  .options-list-text > li:last-child {
    border-radius: 0 0 0 0;
  }
  .options-list-text > li:hover {
    background-color: #ebeef2;
  }
  .options-list-text > li {
    margin-bottom: 0;
    font-size: 12px;
    padding: 4px 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #000;
    display: block;
    cursor: pointer;
    line-height: 14px;
  }
  .input-textarea-span {
    display: inline-block;
    box-sizing: border-box;
    vertical-align: top;
    height: 28px;
    font-size: 12px;
    border: 1px solid rgb(207, 213, 222);
    border-radius: 0px;
    background-color: rgb(255, 255, 255);
    color: rgba(0, 0, 0, 0.9);
    transition: color 0.2s ease-in-out 0s, background-color, border;
    padding: 3px 0px !important;
    min-height: 22px !important;
    line-height: 22px !important;
    resize: none;
  }
</style>
