<script setup lang="ts">
import { computed, watch } from 'vue';
import { useDictStore } from '@/store/modules/dict';
import { useDict } from '@/hooks/business/dict';

defineOptions({ name: 'DictSelect' });

const ensuredEmptyDictCodes = new Set<string>();

interface Props {
  dictCode: string;
  placeholder?: string;
  disabled?: boolean;
  clearable?: boolean;
  filterable?: boolean;
  onlyEnabled?: boolean;
  multiple?: boolean;
  collapseTags?: boolean;
  collapseTagsTooltip?: boolean;
  /** 下拉项右侧追加字典 remark 中文释义（优先级等需要"P0 → 紧急"对照的场景） */
  showRemark?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '请选择',
  disabled: false,
  clearable: true,
  filterable: false,
  onlyEnabled: true,
  multiple: false,
  collapseTags: false,
  collapseTagsTooltip: false,
  showRemark: false
});

const model = defineModel<string | number | Array<string | number> | null | undefined>({
  default: undefined
});

const dictStore = useDictStore();
const { enabledDictData, dictData } = useDict(() => props.dictCode);

const dictOptions = computed(() => {
  const source = props.onlyEnabled ? enabledDictData.value : dictData.value;
  return source.map(item => ({
    label: item.label,
    value: item.value,
    colorType: item.colorType ?? null,
    remark: item.remark ?? null
  }));
});

// 单选时取当前选中项的 colorType，用于触发器 prefix 色块
const selectedColorType = computed<string | null>(() => {
  if (props.multiple) return null;
  const value = model.value;
  if (value === null || value === undefined || value === '') return null;
  return dictOptions.value.find(opt => opt.value === value)?.colorType ?? null;
});

watch(
  () => [props.dictCode, dictOptions.value.length, dictStore.initialized, dictStore.loading] as const,
  async ([dictCode, optionCount, initialized, loading]) => {
    if (!dictCode || optionCount > 0 || !initialized || loading || ensuredEmptyDictCodes.has(dictCode)) {
      return;
    }

    ensuredEmptyDictCodes.add(dictCode);
    await dictStore.ensureDictData(dictCode, true);
  },
  { immediate: true }
);
</script>

<template>
  <ElSelect
    v-model="model"
    class="dict-select w-full"
    :placeholder="props.placeholder"
    :disabled="props.disabled"
    :clearable="props.clearable"
    :filterable="props.filterable"
    :multiple="props.multiple"
    :collapse-tags="props.collapseTags"
    :collapse-tags-tooltip="props.collapseTagsTooltip"
  >
    <template v-if="selectedColorType" #prefix>
      <span class="dict-select__color-dot" :style="{ background: selectedColorType }" />
    </template>
    <ElOption v-for="item in dictOptions" :key="item.value" :label="item.label" :value="item.value">
      <span class="dict-select__option">
        <span
          v-if="item.colorType"
          class="dict-select__color-dot dict-select__color-dot--option"
          :style="{ background: item.colorType }"
        />
        <span class="dict-select__option-label">{{ item.label }}</span>
        <span v-if="props.showRemark && item.remark" class="dict-select__option-remark">{{ item.remark }}</span>
      </span>
    </ElOption>
  </ElSelect>
</template>

<style scoped>
.dict-select__color-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  vertical-align: middle;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.dict-select__color-dot--option {
  margin-right: 8px;
}

.dict-select__option {
  display: inline-flex;
  align-items: center;
  width: 100%;
  gap: 8px;
}

.dict-select__option-label {
  flex: 0 0 auto;
}

.dict-select__option-remark {
  margin-left: auto;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}
</style>
