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

const props = defineProps({
  columns: {
    type: Array,
    default() {
      return []
    },
  },
  option: {
    type: Object,
    default() {
      return { text: 'label', value: 'value', children: 'children' }
    },
  },
  offOption: { // 关闭option配置key-value;当数据是非集合的数组的时候，开启
    type: Boolean,
    default: false,
  },
  border: { // 是否展示边框
    type: Boolean,
    default: false,
  },
  lazyLoad: { // 是否启用懒加载
    type: String,
    default: 'false',
  },
  onSearch: { // 懒加载时的搜索函数
    type: Function,
    default: 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([])

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

      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
      }
    }
    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 变化
watch(() => props.columns, () => {
  columnsData.value = transformColumns(props.columns)
  filteredColumns.value = columnsData.value
  searchValue.value = ''
}, { deep: true })
</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">
    <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>
.loading-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

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