<template>
  <ASelect
    allow-clear
    showSearch
    :filterOption="filterWrapper"
    v-model:value="internalValue"
    mode="multiple"
    :placeholder="placeholder"
    :style="style"
    :options="transformedOptions"
    @blur="handleBlur"

  >
    <template #dropdownRender="{ menuNode: menu }">
      <div style="padding: 4px 8px; border-bottom: 1px solid #f0f0f0">
        <ASpace>
          <AButton size="small" type="link" @click.stop="handleSelectAll">全选</AButton>
          <AButton size="small" type="link" @click.stop="handleInvertSelect">反选</AButton>
          <AButton size="small" type="link" @click.stop="handleClearSelect">清空</AButton>
        </ASpace>
      </div>
      <v-nodes :vnodes="menu"/>
    </template>
  </ASelect>
</template>

<script setup lang="ts">
import {selectFilterOption} from "@/utils/common";
import {defineComponent, computed, watch, ref} from 'vue';

const VNodes = defineComponent({
  props: {
    vnodes: {
      type: Object,
      required: true,
    },
  },
  render() {
    return this.vnodes;
  },
});

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  options: {
    type: Array,
    required: true
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  style: {
    type: Object,
    default: () => ({width: '180px'})
  },
  valueField: {
    type: String,
    default: 'value'
  },
  labelField: {
    type: String,
    default: 'label'
  }
});

const emit = defineEmits(['update:modelValue' ,'change']);

// 使用 ref 管理内部值，确保响应式更新
const internalValue = ref(props.modelValue);

// 监听父组件传入的值变化
watch(() => props.modelValue, (newVal) => {
  internalValue.value = newVal;
});

// 监听内部值变化并通知父组件
watch(internalValue, (newVal) => {
  emit('update:modelValue', newVal);
  emit('change' ,newVal)
});

let filters = {}

const filterWrapper = (input: string, option: any)=>{
  let b = selectFilterOption(input ,option);
  if(b){
    filters[option.value] = option;
  }else{
    //删除
    delete filters[option.value];
  }
  return b;
}

const handleBlur = ()=>{
  filters = {};
}

// 转换后的选项 - 添加原始值引用
const transformedOptions = computed(() => {
  return props.options && props.options.length
    ? props.options.map(item => ({
      value: item[props.valueField],
      label: item[props.labelField],
      text: item[props.labelField],
      raw: item // 保留原始引用
    }))
    : [];
});

// 全选
function handleSelectAll() {
  if(filters && Object.keys( filters).length > 0){
    internalValue.value = Object.keys( filters);
    return;
  }
  internalValue.value = props.options.map(item => item[props.valueField]);
}

// 反选
function handleInvertSelect() {
  const currentSelected = internalValue.value || [];
  if(filters && Object.keys( filters).length > 0){
    internalValue.value = Object.keys( filters).filter(value => !currentSelected.includes(value));
    return;
  }
  const allValues = props.options.map(item => item[props.valueField]);
  internalValue.value = allValues.filter(value => !currentSelected.includes(value));
}

// 清空选择
function handleClearSelect() {
  internalValue.value = [];
}
</script>
