<script setup lang="ts">
import { computed, nextTick, onMounted, ref, unref } from 'vue';
import { useDebounceFn } from '@vueuse/core';
import { get } from '@/utils/zt/lodashChunk';
import { isFunction } from '@/utils/zt/is';
import { basicApiSelectProps } from './props';
import type { ApiSelectProps } from './type';

const debouncedFn = useDebounceFn(() => {
  fetchApi();
}, 1000);

const props = withDefaults(defineProps<ApiSelectProps>(), {
  immediate: true,
  resultFeild: 'data',
  clearable: true,
  pagination: false,
  pageNumFeild: 'current',
  pageSizeFeild: 'size'
});

const fetchLoading = ref(false);
const basicProps = ref(basicApiSelectProps);
const options = ref<Recordable[]>([]);
const modelVlaue = defineModel<Array<string | number> | string | number | null>();
const isFirstReq = ref(false);
const searchText = ref('');
const total = ref(0);
const page = ref(1);
const bindValue = computed(() => {
  return {
    ...props,
    ...basicProps
  };
});

async function fetchApi() {
  const api = props.api;
  if (!api || !isFunction(api)) return;
  const params = {
    ...props.params
  };
  if (unref(bindValue).filterFeild && unref(searchText)) {
    params[String(unref(bindValue).filterFeild)] = unref(searchText);
    // console.log(params, 'apiselect请求参数');
  }
  if (unref(bindValue).pagination) {
    params[unref(bindValue).pageNumFeild] = unref(page);
    params[unref(bindValue).pageSizeFeild] = 10;
  }
  const res = await api(params);
  options.value = unref(bindValue).pagination ? [...options.value, ...res.data.records] : get(res, props.resultFeild);

  fetchLoading.value = false;
  if (props.setDefaultValue) {
    console.log(options.value[0], unref(bindValue).valueFeild, 'options.value');

    nextTick(() => {
      modelVlaue.value = options.value[0][unref(bindValue).valueFeild as string];
      console.log(modelVlaue.value, '默认值');
    });
  }
  if (props.getOptions) {
    props.getOptions(options.value);
  }
  if (unref(bindValue).pagination) {
    total.value = res.data.total;
  }
}
onMounted(() => {
  if (unref(bindValue).immediate) {
    fetchApi();
  }
});

function handleFocus() {
  if (!unref(bindValue).immediate && !unref(isFirstReq)) {
    fetchApi();
    isFirstReq.value = true;
  }
  if (!unref(options).length && unref(bindValue).immediate) {
    fetchApi();
  }
}
function handleScroll(e: Event) {
  const currentTarget = e.currentTarget as HTMLElement;
  if (currentTarget.scrollTop + currentTarget.offsetHeight >= currentTarget.scrollHeight) {
    // console.log('到底了');
    if (options.value.length < total.value && !fetchLoading.value) {
      // console.log('请求数据');
      fetchLoading.value = true;
      page.value += 1;
      fetchApi();
    }
  }
}
function handleSearch(value: string) {
  fetchLoading.value = true;
  searchText.value = value;
  debouncedFn();
}
function handleClear() {
  searchText.value = '';
  fetchApi();
}
function handleBlur() {
  searchText.value = '';
}
</script>

<template>
  <NSelect
    v-bind="bindValue"
    v-model:value="modelVlaue"
    :options="options"
    :label-field="labelFeild"
    :value-field="valueFeild"
    :loading="fetchLoading"
    @focus="handleFocus"
    @scroll="handleScroll"
    @search="handleSearch"
    @clear="handleClear"
    @blur="handleBlur"
  ></NSelect>
</template>

<style scoped></style>
