<template>
  <div class="common-selector-container">
    <el-select
      v-if="!radio"
      v-model="innerValue"
      :placeholder="placeholder"
      :no-data-text="noDataText"
      :disabled="disabled"
      :clearable="clearable"
      style="width: 100%"
      @change="handleChange"
    >
      <el-option
        v-for="(item, index) in currentOptions"
        :key="`${dictName}-${index}`"
        :label="item[labelKey]"
        :value="item[valueKey]"
      ></el-option>
    </el-select>

    <el-radio-group
      v-else
      v-model="innerValue"
      :disabled="disabled"
      @change="handleChange"
      class="common-radio-group"
      :clearable="clearable"
    >
      <el-radio
        v-for="(item, index) in currentOptions"
        :key="`${dictName}-${index}`"
        :value="item[valueKey]"
      >
        {{ item[labelKey] }}
      </el-radio>
    </el-radio-group>
  </div>
</template>

<script setup>
import {
  ref,
  watch,
  defineProps,
  defineEmits,
  onMounted,
  onUnmounted,
} from "vue";

// 极简Props：仅传 v-model + dictName（必传），其余可选
const props = defineProps({
  // 双向绑定值（必传）
  modelValue: {
    type: [String, Number, Object],
    default: undefined,
  },
  // 必传：指定从resourceData中取哪个字典（如dqlx/ zdfx-type/ fileHierarchy）
  dictName: {
    type: String,
    required: true,
  },
  // 可选：自定义选项标签字段（默认name）
  labelKey: {
    type: String,
    default: "name",
  },
  clearable: {
    type: Boolean,
    default: true,
  },

  // 可选：自定义选项值字段（默认key）
  valueKey: {
    type: String,
    default: "key",
  },
  // 可选：是否切换为单选组（默认false=下拉）
  radio: {
    type: Boolean,
    default: false,
  },
  // 可选：是否禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 可选：自定义占位符
  placeholder: {
    type: String,
    default: "请选择",
  },
  // 可选：自定义无数据文本
  noDataText: {
    type: String,
    default: "暂无数据",
  },
});

// 事件派发（v-model规范 + 自定义change）
const emit = defineEmits(["update:modelValue", "change"]);

// 内部状态
const innerValue = ref(props.modelValue); // 内部绑定值
const currentOptions = ref([]); // 最终渲染的字典数据

// 核心方法：从sessionStorage读取resourceData并匹配字典
const getDictFromStorage = () => {
  try {
    // 读取并解析sessionStorage中的resourceData
    const resourceStr = sessionStorage.getItem("resourceData") || "{}";
    const resourceData = JSON.parse(resourceStr);
    // 根据dictName取对应字典，容错：非数组则置空
    const targetDict = resourceData[props.dictName] || [];
    currentOptions.value = Array.isArray(targetDict) ? targetDict : [];
  } catch (e) {
    currentOptions.value = [];
    console.warn(`【通用选择器】读取${props.dictName}字典失败：`, e);
  }
};

// 监听sessionStorage变化（适配resourceData动态更新的场景）
const handleStorageChange = (e) => {
  if (e.key === "resourceData") getDictFromStorage();
};

// 初始化+监听
onMounted(() => {
  getDictFromStorage(); // 首次加载读取字典
  window.addEventListener("storage", handleStorageChange); // 监听storage变化
});

// 销毁时移除监听，避免内存泄漏
onUnmounted(() => {
  window.removeEventListener("storage", handleStorageChange);
});

// 监听1：外部v-model值变化，同步到组件内部
watch(
  () => props.modelValue,
  (newVal) => {
    innerValue.value = newVal;
  },
  { immediate: true },
);

// 监听2：dictName/labelKey/valueKey变化，重新读取字典（适配动态切换字典的场景）
watch(
  () => [props.dictName, props.labelKey, props.valueKey],
  () => {
    getDictFromStorage();
  },
  { deep: true },
);

// 核心：值变化时更新外部v-model
const handleChange = (val) => {
  emit("update:modelValue", val);
  emit("change", val);
};
</script>

<style scoped lang="less">
.common-selector-container {
  width: 100%; // 自适应布局
}
// 单选组间距优化
.common-radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 32px;
  align-items: center;
  width: 100%;
}
// 修复下拉选项宽度继承
:deep(.el-select) {
  width: 100%;
}
</style>
