<template>
  <a-select
    v-model:value="selectedValue"
    :placeholder="placeholder"
    :loading="isLoading"
    :disabled="disabled"
    :allow-clear="allowClear"
    :show-search="true"
    :filter-option="false"
    :not-found-content="notFoundContent"
    :style="{ width: width }"
    :labelInValue="true"
    :getPopupContainer="getSafePopupContainer"
    :dropdownMatchSelectWidth="false"
    :dropdownStyle="{ zIndex: 4000 }"
    @search="handleSearch"
    @change="handleChange"
    @dropdown-visible-change="handleDropdownVisibleChange"
    @popup-scroll="handlePopupScroll"
  >
    <!-- 首次加载时显示加载状态 -->
    <a-select-option v-if="isLoading && allOptions.length === 0" key="initial-loading" value="__initial_loading__" disabled>
      <div style="text-align: center; color: #999">
        <a-spin size="small" />
        <span style="margin-left: 8px">加载中...</span>
      </div>
    </a-select-option>

    <!-- 自定义输入选项放在最前面 -->
    <a-select-option v-if="showCustomInput && customInputValue" key="custom-input" :value="customInputValue" :label="customInputValue"> + 使用: "{{ customInputValue }}" </a-select-option>

    <!-- 有数据时显示选项 -->
    <a-select-option
      v-for="item in allOptions"
      :key="item.id"
      :value="item.name"
      :label="item.name"
      v-memo="[item.id, item.name]"
    >
      {{ item.name }}
    </a-select-option>

    <a-select-option v-if="hasMore && !isPreloading" key="load-more" value="__load_more__" disabled>
      <div @click="loadMore" style="text-align: center; color: #1890ff; cursor: pointer">
        <span>点击加载更多</span>
      </div>
    </a-select-option>

    <a-select-option v-if="isPreloading" key="loading" value="__loading__" disabled>
      <div style="text-align: center; color: #999">
        <a-spin size="small" />
        <span style="margin-left: 8px">加载中...</span>
      </div>
    </a-select-option>
  </a-select>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue';
import { cpMedicinesMethod } from '@/request/api/dictionary.api';
interface Option {
  [key: string]: any;
}

interface Props {
  modelValue?: string | number | undefined;
  options?: Option[];
  placeholder?: string;
  width?: string;
  disabled?: boolean;
  allowClear?: boolean;
  loading?: boolean;
  allowCustomInput?: boolean;
  searchDebounce?: number;
  notFoundContent?: string;
  // 自定义字段名
  valueKey?: string;
  labelKey?: string;
  keyKey?: string;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '请选择或输入',
  width: '100%',
  disabled: false,
  allowClear: true,
  loading: false,
  allowCustomInput: true,
  searchDebounce: 300,
  notFoundContent: '暂无数据',
  valueKey: 'name',
  labelKey: 'name',
  keyKey: 'id',
});

const emit = defineEmits<{
  'update:modelValue': [value: string | number | undefined];
  change: [value: string | number | undefined, option: Option | null];
  search: [keyword: string];
}>();

const selectedValue = ref<string | number | { value: string | number; label: string } | undefined>(undefined);
const searchKeyword = ref('');
const currentPage = ref(1);
const allOptions = ref<Option[]>([]);
const hasMore = ref(false);
const isLoading = ref(false);
const isInitialized = ref(false);
const isPreloading = ref(false);
const isUpdating = ref(false); // 数据更新状态
const lastViewedOptions = ref<Option[]>([]); // 保存上一次的浏览状态
const lastViewedPage = ref(1); // 保存上一次的页码
const lastViewedHasMore = ref(false); // 保存上一次的hasMore状态
const hasInitialData = ref(false); // 标记是否已经有过初始数据

// 节流函数
const throttle = (func: Function, delay: number) => {
  let timeoutId: number | null = null;
  return (...args: any[]) => {
    if (timeoutId) return;
    timeoutId = setTimeout(() => {
      func.apply(null, args);
      timeoutId = null;
    }, delay);
  };
};

// 去重函数
const deduplicateOptions = (options: Option[]) => {
  const seen = new Set();
  return options.filter((option) => {
    const key = option.id;
    if (seen.has(key)) {
      return false;
    }
    seen.add(key);
    return true;
  });
};

// 批量更新数据
const batchUpdateOptions = (newData: Option[]) => {
  isUpdating.value = true;

  // 使用 nextTick 确保批量更新
  nextTick(() => {
    const newOptions = [...allOptions.value, ...newData];
    allOptions.value = deduplicateOptions(newOptions);
    isUpdating.value = false;
  });
};

const showCustomInput = computed(() => {
  return props.allowCustomInput && searchKeyword.value && !allOptions.value.some((option) => option.name.toLowerCase().includes(searchKeyword.value.toLowerCase()));
});

const customInputValue = computed(() => searchKeyword.value.trim());

// 安全获取弹窗容器
function getSafePopupContainer(triggerNode: HTMLElement) {
  return document?.body || triggerNode?.parentNode || triggerNode;
}

watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue) {
      // 查找对应的选项来获取 label
      const option = allOptions.value.find((item) => item.name === newValue);
      if (option) {
        selectedValue.value = { value: newValue, label: option.name };
      } else {
        // 如果是自定义值，直接使用
        selectedValue.value = { value: newValue, label: newValue };
      }
    } else {
      // 当 labelInValue 为 true 时，空值应该是 undefined，而不是空字符串
      selectedValue.value = undefined;
    }
  },
  { immediate: true }
);

let searchTimer: number | null = null;
const debouncedSearch = async (keyword: string) => {
  if (searchTimer) clearTimeout(searchTimer);

  searchTimer = setTimeout(async () => {
    if (!keyword.trim()) {
      // keyword 为空时，恢复上次保存的数据或加载初始数据
      if (hasInitialData.value && lastViewedOptions.value.length > 0) {
        allOptions.value = [...lastViewedOptions.value];
        currentPage.value = lastViewedPage.value;
        hasMore.value = lastViewedHasMore.value;
        return;
      }
      
      // 如果没有保存的数据，加载初始数据
      isLoading.value = true;
      try {
        const result = await cpMedicinesMethod(1, 10, { keyword: '' });
        allOptions.value = deduplicateOptions(result.data);
        currentPage.value = 1;
        hasMore.value = allOptions.value.length < result.total;

        // 保存初始数据状态
        hasInitialData.value = true;
        lastViewedOptions.value = [...allOptions.value];
        lastViewedPage.value = currentPage.value;
        lastViewedHasMore.value = hasMore.value;
      } catch (error) {
        allOptions.value = [];
      } finally {
        isLoading.value = false;
      }
      return;
    }

    isLoading.value = true;
    try {
      const result = await cpMedicinesMethod(1, 10, { keyword });
      allOptions.value = deduplicateOptions(result.data);
      currentPage.value = 1;
      hasMore.value = allOptions.value.length < result.total;

      // 保存搜索结果的浏览状态
      hasInitialData.value = true;
      lastViewedOptions.value = [...allOptions.value];
      lastViewedPage.value = currentPage.value;
      lastViewedHasMore.value = hasMore.value;
    } catch (error) {
      console.error('搜索失败:', error);
      // 搜索失败时不清空数据，保持之前的状态
      if (hasInitialData.value && lastViewedOptions.value.length > 0) {
        allOptions.value = [...lastViewedOptions.value];
        currentPage.value = lastViewedPage.value;
        hasMore.value = lastViewedHasMore.value;
      }
    } finally {
      isLoading.value = false;
    }
  }, props.searchDebounce);
};

const handleSearch = (value: string) => {
  searchKeyword.value = value;
  
  // 如果搜索框被清空，立即恢复数据
  if (!value.trim() && hasInitialData.value && lastViewedOptions.value.length > 0) {
    allOptions.value = [...lastViewedOptions.value];
    currentPage.value = lastViewedPage.value;
    hasMore.value = lastViewedHasMore.value;
    return;
  }
  
  // 使用 nextTick 确保 DOM 更新后再执行搜索
  nextTick(() => {
    debouncedSearch(value);
  });
  emit('search', value);
};

const handleChange = (value: any, option: any) => {
  if (value === '__load_more__' || value === '__initial_loading__' || value === '__loading__' || value === undefined) return;

  // 使用 labelInValue 时，value 是 { value, label } 格式
  // 当用户清空选择时，value 可能是 null
  if (value === null) {
    selectedValue.value = undefined;
    emit('update:modelValue', undefined);
    emit('change', undefined, null);
    return;
  }

  if (typeof value === 'object' && value !== null) {
    selectedValue.value = value.value;
    emit('update:modelValue', value.value);
    emit('change', value.value, option);
  } else {
    selectedValue.value = value;
    emit('update:modelValue', value);
    const selectedOption = allOptions.value.find((option) => option.name === value) || null;
    emit('change', value, selectedOption);
  }
};

const handleDropdownVisibleChange = (visible: boolean) => {
  if (visible) {
    // 展开时，如果没有数据就加载全部数据（不带keyword）
    if (allOptions.value.length === 0) {
      // 如果有保存的数据，先恢复
      if (hasInitialData.value && lastViewedOptions.value.length > 0) {
        allOptions.value = [...lastViewedOptions.value];
        currentPage.value = lastViewedPage.value;
        hasMore.value = lastViewedHasMore.value;
      } else {
        // 否则加载全部初始数据（不带keyword）
        isLoading.value = true;
        cpMedicinesMethod(1, 10, { keyword: '' })
          .then((result) => {
            if (result && result.data && result.data.length > 0) {
              allOptions.value = deduplicateOptions(result.data);
              currentPage.value = 1;
              hasMore.value = allOptions.value.length < result.total;
              isInitialized.value = true;

              // 保存初始数据状态
              hasInitialData.value = true;
              lastViewedOptions.value = [...allOptions.value];
              lastViewedPage.value = currentPage.value;
              lastViewedHasMore.value = hasMore.value;
            }
          })
          .catch((error) => {
            console.error('首次加载失败:', error);
            allOptions.value = [];
          })
          .finally(() => {
            isLoading.value = false;
          });
      }
    }
  } else {
    // 关闭下拉框时，保存当前状态
    if (allOptions.value.length > 0) {
      hasInitialData.value = true;
      lastViewedOptions.value = [...allOptions.value];
      lastViewedPage.value = currentPage.value;
      lastViewedHasMore.value = hasMore.value;
    }
  }
};

// 强制刷新下拉框数据的方法
const forceRefresh = () => {
  allOptions.value = [];
  hasInitialData.value = false;
  lastViewedOptions.value = [];
  lastViewedPage.value = 1;
  lastViewedHasMore.value = false;
  isInitialized.value = false;
  
  // 重新加载数据
  if (allOptions.value.length === 0) {
    isLoading.value = true;
    cpMedicinesMethod(1, 10, { keyword: '' })
      .then((result) => {
        if (result && result.data && result.data.length > 0) {
          allOptions.value = deduplicateOptions(result.data);
          currentPage.value = 1;
          hasMore.value = allOptions.value.length < result.total;
          isInitialized.value = true;

          hasInitialData.value = true;
          lastViewedOptions.value = [...allOptions.value];
          lastViewedPage.value = currentPage.value;
          lastViewedHasMore.value = hasMore.value;
        }
      })
      .catch((error) => {
        console.error('强制刷新失败:', error);
        allOptions.value = [];
      })
      .finally(() => {
        isLoading.value = false;
      });
  }
};

// 节流处理的滚动事件
const throttledScroll = throttle((e: Event) => {
  const target = e.target as HTMLElement;
  const { scrollTop, scrollHeight, clientHeight } = target;

  // 提前触发加载（距离底部80px时就开始加载）
  if (scrollHeight - scrollTop <= clientHeight + 80 && hasMore.value && !isLoading.value && !isPreloading.value && !isUpdating.value) {
    loadMore();
  }
}, 50);

const handlePopupScroll = (e: Event) => {
  throttledScroll(e);
};

const loadMore = async () => {
  if (isLoading.value || !hasMore.value || isPreloading.value || isUpdating.value) return;

  isPreloading.value = true;
  try {
    const nextPage = currentPage.value + 1;

    // 加载更多时也不带keyword，加载全部数据
    const result = await cpMedicinesMethod(nextPage, 10, { keyword: '' });

    // 批量更新数据，避免逐条渲染
    batchUpdateOptions(result.data);

    // 立即更新状态
    currentPage.value = nextPage;
    hasMore.value = allOptions.value.length < result.total;

    // 更新上一次浏览状态
    hasInitialData.value = true;
    lastViewedOptions.value = [...allOptions.value];
    lastViewedPage.value = currentPage.value;
    lastViewedHasMore.value = hasMore.value;
  } catch (error) {
    console.error('加载更多失败:', error);
  } finally {
    isPreloading.value = false;
  }
};

const resetOptions = () => {
  allOptions.value = [];
  currentPage.value = 1;
  hasMore.value = false;
  isInitialized.value = false;
  isPreloading.value = false;
  isUpdating.value = false;
  // 清空上一次浏览状态
  hasInitialData.value = false;
  lastViewedOptions.value = [];
  lastViewedPage.value = 1;
  lastViewedHasMore.value = false;
};

defineExpose({
  resetOptions,
  loadMore,
  search: handleSearch,
  forceRefresh,
});
</script>

<style scoped>
:deep(.ant-select-dropdown) {
  max-height: 300px;
}

:deep(.ant-select-item-option-disabled) {
  cursor: pointer !important;
  color: inherit !important;
}

:deep(.ant-select-item-option-disabled:hover) {
  background-color: #f5f5f5 !important;
}
</style>
