<template>
  <el-select
    v-model="cvalue"
    class="base-selector"
    popper-class="base-selector-popper"
    ref="elselect"
    clearable
    :filterable="config.filterable"
    :filter-method="config.filterMethod ? config.filterMethod : filterMethod"
    :multiple="config.multiple"
    :remote-method="config.remote ? remoteFilter : null"
    :remote="config.remote"
    :placeholder="computePlaceholder"
    :loading="loading"
    v-bind="$attrs"
    @change="changeSelect"
  >
    <template #prefix v-if="config.filterable">
      <font-awesome-icon :icon="['fas', 'search']" />
    </template>
    <el-checkbox v-if="config.multiple && config.useSelectAll" v-model="checked" @change="selectAll">全选</el-checkbox>
    <el-option
      v-for="item in optionData"
      :disabled="doDisabledOptionsBy(item)"
      v-show="!doDisabledOptionsBy(item)"
      :key="item[optionProps.key]"
      :label="item[optionProps.label]"
      :value="item[optionProps.value]"
    />
    <slot name="loadMore"></slot>
  </el-select>
</template>

<script setup>
  import { ref, computed, watch, onMounted } from 'vue'

  const props = defineProps({
    config: {
      type: Object,
      default: () => ({
        remote: false,
        filterable: false,
        multiple: false,
        useSelectAll: true,
        filterMethod: null,
      }),
    },
    optionProps: {
      type: Object,
      default: () => ({ key: 'value', label: 'display', value: 'value' }),
    },
    modelValue: {
      type: [Array, String, Number],
      default: () => (config.multiple ? [] : ''),
    },
    data: {
      type: Array,
      default: () => [],
    },
    disabledOptions: {
      type: Array,
      default: () => [],
    },
    disabledOptionsBy: Function,
    placeholder: String,
  })

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

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

  const computePlaceholder = computed(() => props.placeholder || (props.config.filterable ? '请输入查找内容' : '请选择'))

  const optionData = ref(props.data)

  // 方法
  const doDisabledOptionsBy = (item) =>
    props.disabledOptionsBy ? props.disabledOptionsBy(item) : props.disabledOptions.includes(item[props.optionProps.value])

  const remoteFilter = (query) => {
    loading.value = true
    setTimeout(() => {
      loading.value = false
      emit('remote-filter', query)
    }, 200)
  }

  const filterMethod = (query) => {
    if (!query) optionData.value = props.data

    optionData.value = props.data.filter((option) => {
      const label = option[props.optionProps.label]
      const value = option[props.optionProps.value]

      return label.toLowerCase().includes(query.toLowerCase()) || value.toString().toLowerCase().includes(query.toLowerCase())
    })
  }

  const selectAll = () => {
    cvalue.value = checked.value ? optionData.value.map((obj) => obj[props.optionProps.value]) : []
  }

  const changeSelect = (val) => {
    checked.value = Array.isArray(val) ? val.length === optionData.value.length : false
    emit('change', val)
  }

  watch(
    () => props.data,
    (val) => {
      optionData.value = val
    }
  )
  // 生命周期
  onMounted(() => {
    emit('select-load-option')
  })
</script>

<style lang="scss">
  .base-selector {
    .filter-prefix {
      text-align: center;
      width: 25px;
    }
  }
  .base-selector-popper {
    .left-info-bar {
      font-size: 12px;
      padding: 0 20px;
      position: relative;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      height: 34px;
      line-height: 34px;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      cursor: pointer;
      color: var(--el-color-primary);
      font-weight: 700;
      font-weight: 700;
    }
  }
</style>
