<template>
  <base-selector v-model="cvalue"
                 ref="bselect"
                 :config="config"
                 :optionProps="optionProps"
                 :data="data"
                 :total="total"
                 :disabled-options="disabledOptions"
                 :disabled-options-by="disabledOptionsBy"
                 :use-select-all="useSelectAll"
                 @show-more="showMore"
                 @remote-filter="queryDictItems"
                 @selected-clear="clear"
                 @visible-change="visibleChange"
                 v-bind="$attrs"
                 @change="change"
                 @select-load-option="initData">
  </base-selector>
</template>

<script setup>
import BaseSelector from './BaseSelector.vue'
import { DICTS } from '@/utils/Constants'
import dictItems from '../api/system/DictItems'
import { computed, ref, watch, reactive, toRefs } from 'vue'
import { useConstantStore } from '@/stores/modules/constant'

const props = defineProps({
  dictCode: String,
  sort: { type: String, default: 'orderNum' },
  dir: { type: String, default: 'asc' },
  filterable: { type: Boolean, default: false },
  multiple: { type: Boolean, default: false },
  defaultOptions: { type: Array, default: () => [] },
  modelValue: { // Vue3 v-model 替换原value
    type: [Array, String, Number],
    default: null
  },
  limit: {
    type: Number,
    default: 0
  },
  valueMarray: { type: String, default: null },
  remote: { type: Boolean, default: false },
  dictFilter: {
    type: Function,
    default: (dictItem, query, optionProps = { value: 'xxdm', label: 'xxdmmc' }) =>
      !query ||
      query === dictItem[optionProps.value] ||
      dictItem[optionProps.label]?.includes(query) ||
      (dictItem.simplePinyin?.includes(query)) ||
      (dictItem.allPinyin?.includes(query))
  },
  banFilter: {
    type: Function,
    default: () => false
  },
  disabledOptions: Array,
  disabledOptionsBy: Function,
  useSelectAll: { type: Boolean, default: true }
})

const emit = defineEmits([
  'update:modelValue',
  'selected',
  'visible-change',
  'select-load-option'
])

const store = useConstantStore()
const bselect = ref(null)

// 响应式状态
const state = reactive({
  params: {
    dictCode: props.dictCode,
    sort: props.sort,
    dir: props.dir,
    valueMarray: props.valueMarray
  },
  optionProps: { key: 'xxdmbh', label: 'xxdmmc', value: 'xxdm' },
  page: 1,
  lQueryParam: null,
  cacheFirstData: { data: [], total: 0 },
  data: [],
  total: 0,
  config: {
    filterable: props.filterable,
    multiple: props.multiple,
    remote: props.remote
  }
})

// 方法定义
const localFilterMethod = (q) => {
  if (q) {
    if (props.filterMethod && typeof props.filterMethod === 'function') {
      state.data = props.filterMethod(q, state.cacheFirstData.data)
    } else {
      state.data = state.cacheFirstData.data.filter(dictItem => {
        const value = dictItem[state.optionProps.value] || ''
        const label = dictItem[state.optionProps.label] || ''
        return value.includes(q) ||
          label.includes(q) ||
          dictItem.simplePinyin?.includes(q) ||
          dictItem.allPinyin?.includes(q)
      })
    }
  } else {
    state.data = state.cacheFirstData.data
  }
}

const change = (v) => {
  if (props.multiple) {
    const temp = v.map(vl =>
      state.data.find(d => d[state.optionProps.value] === vl)
    )
    emit('selected', v, temp, state.data)
  } else {
    emit('selected', v, state.data.find(d => d[state.optionProps.value] === v), state.data)
  }
}

const visibleChange = (opened) => {
  if (!opened && !state.data.length) {
    queryDictItems()
  }
}

const initData = () => {
  if (props.remote && props.modelValue) {
    queryDictItems(null, props.modelValue)
  } else {
    queryDictItems()
  }
}

const queryDictItems = async (select, query, isShowMore = false) => {
  if (!props.dictCode) return

  if (state.lQueryParam !== query) {
    state.page = 1
    state.lQueryParam = query
  }

  try {
    // 根据不同的字典类型调用不同的接口
    let res;
    if (state.params.dictCode === DICTS.DM_XZQH) {
      res = await dictItems.query({
        page: state.page,
        pagesize: props.limit > 0 ? props.limit : undefined,
        ...state.params,
        queryParam: query
      })
    } else {
      // 使用新接口 queryGzt
      res = await dictItems.queryGzt({
        ...state.params,
        queryParam: query
      })
    }

    let pageable = null
    let data = []
    
    // 处理不同类型的返回结果
    if (Array.isArray(res)) {
      // 如果直接返回数组（store.queryDictData 的情况）
      data = res
    } else if (res?.success) {
      if (state.params.dictCode !== DICTS.DM_XZQH) {
        // 处理 queryGzt 返回的数据
        data = res.data || []
      } else {
        // 如果返回对象（dictItems.query 的情况）
        pageable = {
          page: res.page,
          pagesize: res.pagesize,
          limit: res.pagesize,
          total: res.total
        }
        data = res.data
      }
    }

    if (state.params.dictCode !== DICTS.DM_XZQH && props.valueMarray) {
      const valueArray = props.valueMarray.split(',')
      data = data.filter(resmap =>
        valueArray.some(va => resmap[state.optionProps.value].startsWith(va))
      )
      if (pageable) pageable.total = data.length
    }

    responseProcess([data, isShowMore, query, pageable])
  } catch (error) {
    console.error('字典项查询失败:', error)
  }
}

const showMore = (select) => {
  state.page += 1
  queryDictItems(select, state.lQueryParam, true)
}

const clear = (select) => {
  state.total = state.cacheFirstData.total
  state.data = state.cacheFirstData.data
  state.page = 1
  queryDictItems(select, '', false)
}

const responseProcess = ([data, isShowMore, query, pageable]) => {
  // 确保数据是数组
  if (!Array.isArray(data)) {
    console.error('字典数据格式错误:', data)
    return
  }
   
  if (props.limit > 0) {
    if (isShowMore) {
      if (pageable) {
        state.data = [...state.data, ...data]
        state.total = pageable.total
      } else {
        const filterData = data
          .filter(d => props.dictFilter(d, query, state.optionProps))
          .filter(d => !props.banFilter(d))
        state.data.push(...filterData.slice(
          (state.page - 1) * props.limit,
          state.page * props.limit
        ))
        state.total = filterData.length
      }
    } else {
      if (pageable) {
        state.data = data
        state.total = pageable.total
      } else {
        state.page = 1
        const filterData = data
          .filter(d => props.dictFilter(d, query, state.optionProps))
          .filter(d => !props.banFilter(d))
        state.data = filterData.slice(
          (state.page - 1) * props.limit,
          state.page * props.limit
        )
        state.total = filterData.length
        state.cacheFirstData = { data: state.data, total: state.total }
      }
    }
  } else {
    state.data = data.filter(d => !props.banFilter(d))
    state.total = 0
    state.page = 1
    state.cacheFirstData = { data: state.data, total: 0 }
  }
}

// 计算属性
const cvalue = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

// 暴露组件方法给父组件
defineExpose({
  queryDictItems,
  clear,
  showMore
})

// 监听器
watch(() => props.dictCode, (code) => {
  if (code) {
    state.params.dictCode = code
    queryDictItems(bselect.value)
  }
})

watch(() => props.modelValue, (v) => {
  if (props.remote && v) {
    // 检查当前选中的值是否在已加载的数据中
    const hasValue = Array.isArray(v) 
      ? v.every(item => state.data.some(d => d[state.optionProps.value] === item))
      : state.data.some(d => d[state.optionProps.value] === v)
    
    if (!hasValue) {
      state.page = 1
      queryDictItems(bselect.value, v)
    }
  }
})

watch(() => props.valueMarray, (v) => {
  state.params.valueMarray = v
  queryDictItems(bselect.value)
})

const {data,total,page,cacheFirstData,optionProps,config} = toRefs(state)
</script>
