<script setup lang="ts">
import { useDebounceFn } from "@vueuse/core";
import { ref, onMounted, reactive, onUnmounted, watch } from "vue";
import { getCategories } from "/@/api/user";
import { useResponseHandle } from "/@/hooks/core/useAsync";
import { useCompany } from "/@/hooks/core/useCompany";
import { useUserInfo } from "/@/hooks/core/useUser";

import { useVModel } from "@vueuse/core"

const emit = defineEmits(["change", "update:modelValue"]);


const props = withDefaults(
  defineProps<{
    noAll?: boolean;
    noSet?: boolean;
    modelValue?: string;
    isSupplier?: boolean;
    placeholder?: string;
    classWrapper?:string
  }>(),
  {
    modelValue: "",
    classWrapper: 'procure-item'
  }
);

const value = useVModel(props, 'modelValue')


const { setCurrentCompany } = useCompany();
const responseHandle = useResponseHandle();

const { userLevel } = useUserInfo();

const selectRef = ref(null);
const list = ref<any[]>([]);

const state = reactive({
  loading: false,
  noMore: false,
  name: "",
  count: 0,
  page: 1
});

let scrollWrapper: HTMLDivElement | null = null;

const debouceScroll = useDebounceFn(handleScroll, 500);

async function requesetSupplierAll(name: string) {
  state.name = name;
  state.page = 1;
  state.noMore = false;
  const api = getCategories
  const { data, message, code } = await api({
    cat_name: name,
    size:10,
    page: state.page
  });

  responseHandle({
    code,
    message,
    handler: () => {
      list.value = data.list.map(({ short_name, cat_name, merge_code,tax }) => ({
        tax,
        subTitle: short_name,
        value: merge_code,
        label: cat_name
      }))

      state.count = data.count;
      state.loading = false;
      const maxPage = Math.ceil(state.count / 10);
      state.noMore = maxPage <= 1;
    }
  });
}

function handleChange(v) {
  const item = list.value.find(({ value }) => v === value);
  console.log(list.value, value, item)
  emit("change", item);
}

async function handleScroll() {
  const height = scrollWrapper?.clientHeight;
  const scrollTop = scrollWrapper?.scrollTop;
  const scrollHeight = scrollWrapper?.scrollHeight;

  if (height + scrollTop >= scrollHeight && !state.noMore) {
    state.page++;
    state.loading = true;

    const api = getCategories


    const { data, message, code } = await api({
      cat_name: state.name,
      page: state.page,
      size:10,
      noRela: true
    });

    const pushCompany = (_list: any[]) => {
      list.value = [...list.value, ..._list.map(({ short_name, cat_name, merge_code, tax }) => ({
        tax,
        subTitle: short_name,
        value: merge_code,
        label: cat_name
      }))];
    };

    responseHandle({
      code,
      message,
      handler: () => {
        state.count = data.count;
        const maxPage = Math.ceil(state.count / 10);

        if (state.page > maxPage) {
          state.noMore = true;
          state.loading = false;
          return;
        }

        pushCompany(data.list);
      }
    });
  }
}

onMounted(() => {
  setTimeout(() => {
    const superItem = document.querySelector("." + props.classWrapper);
    if (!superItem) return;
    scrollWrapper = superItem.parentElement?.parentElement as HTMLDivElement;
    if (scrollWrapper) {
      scrollWrapper.addEventListener("scroll", debouceScroll, false);
    }
  }, 1000);
});

onUnmounted(() => {
  state.loading = false;
  state.noMore = false;
  state.name = "";
  state.page = 1;

  if (scrollWrapper) {
    scrollWrapper.removeEventListener("scroll", debouceScroll);
  }
});

watch(
  () => userLevel.value,
  level => {
    if (level !== "") {
      state.loading = false;
      state.noMore = false;
      state.name = "";
      state.page = 1;
      list.value = [];
      requesetSupplierAll(undefined);
    }
  }
);

const getLabel = company => {
  const { value, label } = company;
  return value + " / " + label;
};



const getLabel2 = company => {
  const { value, label, subTitle } = company;
  return value + " / " + label + '-' + subTitle;
};


requesetSupplierAll(undefined);


defineExpose({
  async initalData(params){
    const { data, message, code } = await getCategories(params);

    list.value = (data.list || []).map(({ tax, cat_name ,merge_code, short_name }) => ({
      tax,
      value: merge_code,
      label: cat_name,
      subTitle: short_name
    }))

    value.value = (list.value[0] || {}).value
    emit('change', list.value[0], true)
  }
})

</script>

<template>
  <ElSelect
    filterable
    remote
    v-model="value"
    :remote-method="requesetSupplierAll"
    @change="handleChange"
    style="width: 100%"
    ref="selectRef"
    placeholder="商品类目"
  >
    <ElOption
      :class="classWrapper"
      v-for="item in list"
      :key="item.value"
      :value="item.value"
      :label="getLabel2(item)"
    >
      <span style="float: left">
         {{getLabel(item)}}
      </span>

      <span style="float: right;color: var(--el-text-color-secondary);font-size: 13px;">
        {{item.subTitle}}
      </span>
    </ElOption>

    <p class="super-loading" v-if="state.loading">
      <IconifyIconOffline class="animate-spin" icon="Loading" />
      加载中
    </p>

    <p class="super-no-more" v-if="state.noMore">没有更多数据了...</p>
  </ElSelect>
</template>

<style lang="scss" scoped>
.super-no-more {
  text-align: center;
  color: #999;
  font-size: 14px;
  line-height: 38px;
}

.super-loading {
  display: flex;
  font-size: 14px;
  justify-content: center;
  align-items: center;
  color: #999;
  gap: 10px;
  line-height: 38px;
}
</style>
