<template>
  <el-select
    v-model="selected"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    filterable
    default-first-option
    v-bind="attrs"
    @change="onChange"
  >
    <el-option
      v-for="item in optionList"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    />
  </el-select>
</template>

<script setup lang="ts">
  import { ref, useAttrs, watch } from 'vue';
  import { subjectQuery } from '@/api/base';
  import { useAppStore } from '@/store';

  const appStore = useAppStore();

  defineOptions({
    name: 'SelectSubject',
  });
  type ValueType = string | Array<string> | null;

  const props = withDefaults(
    defineProps<{
      modelValue: ValueType;
      clearable?: boolean;
      disabled?: boolean;
      placeholder?: string;
      multiple?: boolean;
    }>(),
    {
      clearable: true,
      disabled: false,
      placeholder: '请选择科目',
      multiple: false,
    }
  );
  const emit = defineEmits(['update:modelValue', 'change']);
  const attrs = useAttrs();

  interface OptionListItem {
    value: string;
    label: string;
  }

  const selected = ref<string | Array<string> | undefined>();
  const optionList = ref<OptionListItem[]>([]);
  const search = async () => {
    if (!appStore.curExam?.id) return;
    const res = await subjectQuery(appStore.curExam?.id);
    optionList.value = res.map((item) => {
      return { ...item, value: item.code, label: item.name };
    });
  };
  search(); // Initial load

  const onChange = () => {
    const selectedData = props.multiple
      ? optionList.value.filter(
          (item) =>
            selected.value && (selected.value as number[]).includes(item.value)
        )
      : optionList.value.filter((item) => selected.value === item.value);
    emit('update:modelValue', selected.value || null);
    emit('change', props.multiple ? selectedData : selectedData[0]);
  };

  watch(
    () => props.modelValue,
    (val) => {
      selected.value = val || undefined;
    },
    {
      immediate: true,
    }
  );
</script>
