<script setup lang="ts">
import {
  Field as VanField,
  Picker as VanPicker,
  Popup as VanPopup,
  Search as VanSearch,
} from 'vant'
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'

const props = withDefaults(defineProps<{
  columns?: any[]
  option?: Record<string, string>
  offOption?: boolean
  border?: boolean
  lazyLoad?: string
  onSearch?: ((searchValue: string) => Promise<any[]>) | null
}>(), {
  columns: () => [],
  option: () => ({ text: 'label', value: 'value', children: 'children' }),
  offOption: false,
  border: false,
  lazyLoad: 'false',
  onSearch: null,
})
const emits = defineEmits(['confirm', 'change', 'cancel', 'input'])
const show = ref(false)
const resultValue = defineModel()
const columnsData = ref([])
const selectedOption = ref([])
const searchValue = ref('')
const isLoading = ref(false)

// 转换空children为空字符串
function transformColumns(data) {
  return data.map((item) => {
    if (item.children && item.children.length === 0) {
      return {
        ...item,
        children: '',
      }
    }
    else if (item.children && item.children.length !== 0) {
      return { ...item, children: transformColumns(item.children) }
    }
    else {
      return { ...item }
    }
  })
}
const filteredColumns = ref([])

// 搜索防抖
const searchDebounceTimer = ref<number | null>(null)

// 监听搜索值变化
const stopWatchSearchValue = watch(
  () => searchValue.value,
  async (newValue) => {
    // 清除之前的防抖定时器
    if (searchDebounceTimer.value !== null) {
      clearTimeout(searchDebounceTimer.value)
      searchDebounceTimer.value = null
    }

    if (props.lazyLoad && props.lazyLoad === 'true' && props.onSearch) {
      if (!newValue) {
        filteredColumns.value = []
        return
      }

      // 防抖延迟
      searchDebounceTimer.value = window.setTimeout(async () => {
        isLoading.value = true
        try {
          const results = await props.onSearch(newValue)
          filteredColumns.value = transformColumns(results || [])
        }
        catch (error) {
          console.error('懒加载搜索失败:', error)
          filteredColumns.value = []
        }
        finally {
          isLoading.value = false
        }
      }, 300)
    }
    else {
      // 普通搜索模式
      if (!newValue) {
        filteredColumns.value = columnsData.value
        return
      }

      const searchTextLower = newValue.toLowerCase()
      filteredColumns.value = columnsData.value.filter((item) => {
        const text = props.offOption ? item : item[props.option.text]
        return text?.toString().toLowerCase().includes(searchTextLower)
      })
    }
  },
  { immediate: true },
)

onBeforeMount(() => {
  columnsData.value = transformColumns(props.columns)
  filteredColumns.value = columnsData.value
})

const resultLabel = computed({
  get() {
    if (!resultValue.value)
      return ''
    const res = props.columns.filter((item) => {
      const data = props.offOption ? item : item[props.option.value]
      return data === resultValue.value
    })
    return res.length ? (props.offOption ? res[0] : res[0][props.option.text]) : ''
  },
  set() {

  },
})

function onConfirm(value, _index) {
  resultValue.value = props.offOption ? value.selectedValues : value.selectedValues[0]
  // resultValue.value = value.selectedValues
  selectedOption.value = value.selectedOptions
  show.value = !show.value
  emits('confirm', value.selectedValues[0], value.selectedOptions)
}

function change(val, index) {
  emits('change', val, index, resultValue.value)
}

function cancel(val, index) {
  show.value = !show.value
  emits('cancel', val, index, resultValue.value)
}

function showPopu(disabled) {
  if (disabled !== undefined && disabled !== false)
    return false
  columnsData.value = transformColumns(props.columns)
  filteredColumns.value = columnsData.value
  searchValue.value = '' // 重置搜索
  show.value = !show.value
}

watch(() => resultValue, (newVal, _oldVal) => {
  columnsData.value = transformColumns(props.columns)
  filteredColumns.value = columnsData.value
  emits('input', newVal)
})

// 监听 columns 变化
const stopWatchColumns = watch(() => props.columns, () => {
  columnsData.value = transformColumns(props.columns)
  filteredColumns.value = columnsData.value
  searchValue.value = ''
}, { deep: true })

onBeforeUnmount(() => {
  // 停止所有 watch，防止内存泄漏
  stopWatchSearchValue()
  stopWatchColumns()
  // 清理未执行的 setTimeout
  if (searchDebounceTimer.value !== null) {
    clearTimeout(searchDebounceTimer.value)
    searchDebounceTimer.value = null
  }
  show.value = false
})
</script>

<template>
  <VanField
    v-model="resultLabel"
    v-bind="$attrs"
    readonly
    :is-link="true"
    :border="props.border"
    @click="showPopu($attrs.readonly)"
  />
  <VanPopup v-model:show="show" position="bottom" teleport="body" round>
    <div class="x-select-popup">
      <!-- 搜索框 -->
      <VanSearch
        v-model="searchValue"
        placeholder="搜索"
      />

      <!-- 选择器 -->
      <VanPicker
        :loading="isLoading"
        v-bind="$attrs"
        :columns="filteredColumns"
        :columns-field-names="props.option"
        show-toolbar
        :value-key="props.option.text"
        @cancel="cancel"
        @confirm="onConfirm"
        @change="change"
      />
    </div>
  </VanPopup>
</template>

<style scoped>
.x-select-popup {
  max-height: 70vh;
  padding-bottom: env(safe-area-inset-bottom);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.x-select-popup :deep(.van-picker) {
  flex: 1;
  min-height: 0;
}

.x-select-popup :deep(.van-picker__columns) {
  max-height: 40vh;
}

.loading-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.loading-text {
  color: #969799;
  font-size: 14px;
}
</style>
