<template>
  <el-drawer :model-value="true" title="新建字典" @close="handleClose" :size="600">
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="add-dict-form">
      <el-form-item label="字典名称" prop="dictName">
        <el-input v-model="formData.dictName" placeholder="请输入字典名称" />
      </el-form-item>

      <el-form-item label="字典编码" prop="dictCode">
        <el-input v-model="formData.dictCode" placeholder="请输入字典编码" />
      </el-form-item>

      <el-form-item label="字典分类" prop="dictType">
        <el-select v-model="formData.dictType" placeholder="请选择字典分类">
          <el-option
            v-for="(item, index) in dictionaryTypeOptions"
            :key="index"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <div class="subDictWrapper">
        <div class="el-form-item__label" style="width: 100px">字典项</div>
        <div class="subDictList">
          <div>
            <div v-for="(item, index) in formData.sysDictDataList" :key="index" class="dict-item-group">
              <!-- 移动按钮 -->
              <div class="dict-item-header">
                <div class="move-buttons">
                  <MoveButton v-if="index > 0" type="up" @move="moveDictItem(index, $event)" />
                  <MoveButton
                    v-if="index < formData.sysDictDataList.length - 1"
                    type="down"
                    @move="moveDictItem(index, $event)"
                  />
                  <el-button
                    v-if="formData.sysDictDataList.length > 1"
                    link
                    class="delete-botton"
                    @click="removeDictItem(index)"
                  >
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
              </div>

              <el-form-item
                :label="`字典项值`"
                :prop="`sysDictDataList.${index}.itemValue`"
                :rules="[{ required: true, message: '请输入字典项值', trigger: 'blur' }]"
              >
                <el-input
                  v-model="item.itemValue"
                  placeholder="请输入字典项值"
                  type="textarea"
                  show-word-limit
                  maxlength="500"
                />
              </el-form-item>
              <el-form-item
                :label="`字典项编码`"
                :prop="`sysDictDataList.${index}.itemCode`"
                :rules="[{ required: true, message: '请输入字典项编码', trigger: 'blur' }]"
              >
                <el-input
                  v-model="item.itemCode"
                  placeholder="请输入字典项编码"
                  type="textarea"
                  show-word-limit
                  maxlength="500"
                />
              </el-form-item>
              <el-form-item label="图标">
                <!-- // 在模板部分修改上传组件的ref绑定 -->
                <el-upload
                  :ref="(el) => setUploadRef(index, el)"
                  v-model:file-list="item.fileList"
                  :auto-upload="false"
                  list-type="picture-card"
                  :limit="1"
                  :on-change="(file) => handleChange(file, index)"
                  :on-exceed="(files) => handleExceed(files, index)"
                >
                  <el-icon><Plus /></el-icon>
                  <template #file="{ file }">
                    <div>
                      <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
                      <span class="el-upload-list__item-actions">
                        <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                          <el-icon><zoom-in /></el-icon>
                        </span>
                        <span class="el-upload-list__item-delete" @click="handleRemove(index)">
                          <el-icon><Delete /></el-icon>
                        </span>
                      </span>
                    </div>
                  </template>
                </el-upload>
              </el-form-item>
            </div>
          </div>
        </div>
      </div>

      <el-form-item>
        <el-button type="primary" link @click="addDictItem">
          <el-icon :size="16">
            <CirclePlus />
          </el-icon>
          <span class="add-text">新增</span>
        </el-button>
      </el-form-item>

      <el-form-item label="字典描述" prop="description">
        <el-input
          v-model="formData.description"
          type="textarea"
          :rows="3"
          placeholder="请输入字典描述"
          maxlength="1000"
          show-word-limit
        />
      </el-form-item>

      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio-button v-for="item in dictionaryStatusOptions" :key="item.value" :value="item.value">{{
            item.label
          }}</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <div class="form-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSubmit">提交</el-button>
      </div>
    </el-form>
  </el-drawer>

  <el-dialog v-model="dialogVisible" width="30%">
    <div class="dialog-content">
      <img :src="dialogImageUrl" alt="Preview Image" />
    </div>
  </el-dialog>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch } from 'vue';
  import {
    ElForm,
    ElFormItem,
    ElInput,
    ElSelect,
    ElOption,
    ElButton,
    ElRadioGroup,
    ElRadioButton,
    ElUpload,
    ElIcon,
    ElDialog,
    FormInstance,
    FormRules,
    UploadProps,
    UploadUserFile,
    UploadInstance,
    UploadRawFile,
    genFileId,
    ElMessage,
  } from 'element-plus';
  import { Plus, Delete, CirclePlus } from '@element-plus/icons-vue';
  import { dictionaryTypeOptions, DictionaryStatus, dictionaryStatusOptions } from '../constants';
  import { queryDictTypeDetail } from '@/api/dict';
  import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
  import { cloneDeep } from 'lodash-es';
  import MoveButton from './MoveButton.vue';

  interface SysDictDataItem {
    id?: string | number; // 可选，用于编辑时
    dictId: string | number | undefined; // 关联的字典ID
    dictCode: string;
    itemValue: string;
    itemCode: string;
    itemSort: number | undefined;
    isDefault: 0 | 1;
    imageUrl?: string; // 用于显示已上传的图片
    status: DictionaryStatus.disabled | DictionaryStatus.enabled;
    fileList?: FileListItem[]; // 用于图片上传;
  }

  interface FileListItem {
    name: string;
    url: string;
  }

  interface FormData {
    dictId?: string | number; // 可选，用于编辑时
    dictName: string;
    dictCode: string;
    dictType: string;
    sysDictDataList: SysDictDataItem[];
    description: string;
    status: DictionaryStatus.disabled | DictionaryStatus.enabled;
  }

  const props = defineProps({
    dictCode: {
      type: String,
      default: '',
    },
  });

  const emit = defineEmits(['submit', 'close']);
  const handleClose = () => {
    emit('close');
  };

  const formRef = ref<FormInstance>();
  const formData = reactive<FormData>({
    dictName: '',
    dictCode: '',
    dictType: '',
    sysDictDataList: [
      {
        id: undefined,
        dictId: undefined,
        dictCode: '',
        itemCode: '',
        itemValue: '',
        itemSort: 1, // 默认排序值
        isDefault: 0,
        status: DictionaryStatus.disabled,
        imageUrl: '',
      },
    ],
    description: '',
    status: DictionaryStatus.disabled,
  });

  watch(
    () => props.dictCode,
    async (newCode) => {
      if (!newCode) return;

      const res = await queryDictTypeDetail(newCode);

      // 处理字典项数据转换
      const processDictItem = (item: any) => ({
        ...item,
        fileList: item.imageUrl
          ? [
              {
                name: item.imageUrl.split('/').pop() || '',
                url: item.imageUrl,
              },
            ]
          : [],
      });

      Object.assign(formData, {
        ...res,
        sysDictDataList: res.sysDictDataList?.map(processDictItem) ?? [],
      });
    },
    { immediate: true },
  );

  const formRules = reactive<FormRules<FormData>>({
    dictName: [{ required: true, message: '请选择字典名称', trigger: 'change' }],
    dictCode: [{ required: true, message: '请选择字典编码', trigger: 'change' }],
    dictType: [{ required: true, message: '请选择字典分类', trigger: 'change' }],
    description: [{ max: 1000, message: '描述不超过1000字', trigger: 'blur' }],
    status: [{ required: true, message: '请选择状态', trigger: 'change' }],
  });

  const addDictItem = () => {
    formData.sysDictDataList.push({
      id: undefined,
      dictId: formData.dictId,
      dictCode: formData.dictCode,
      itemCode: '',
      itemValue: '',
      itemSort: 1, // 默认排序值
      isDefault: 0,
      status: DictionaryStatus.disabled,
      imageUrl: '',
    });
  };

  const removeDictItem = (index: number) => {
    formData.sysDictDataList.splice(index, 1);
  };

  // 图片上传相关
  const dialogImageUrl = ref('');
  const dialogVisible = ref(false);

  const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
    dialogImageUrl.value = uploadFile.url!;
    dialogVisible.value = true;
  };

  const handleRemove = (itemIndex: number) => {
    if (formData.sysDictDataList[itemIndex]) {
      formData.sysDictDataList[itemIndex].imageUrl = ''; // 如果有单独的 URL 字段
      formData.sysDictDataList[itemIndex].fileList = [];
    }
  };

  const handleChange = (uploadFile: UploadUserFile, itemIndex: number) => {
    // Element Plus 的 onChange 会在文件状态改变时触发多次，通常在 ready 状态时文件已可选
    // 这里简单地将文件对象存起来，实际上传应在 handleSubmit 中处理
    if (formData.sysDictDataList[itemIndex]) {
      if (!uploadFile.raw) return;

      uploadFileApi({
        file: uploadFile.raw,
        bizType: UPLOAD_BIZ_TYPE['DICTIONARY'],
        fileName: uploadFile.raw.name,
      }).then((res) => {
        formData.sysDictDataList[itemIndex].imageUrl = res.url;
      });
    }
  };

  // 添加上传组件引用数组
  const uploadRefs = ref<UploadInstance[]>([]);
  const setUploadRef = (index: number, el: any) => {
    uploadRefs.value[index] = el;
  };

  // 修改handleExceed方法
  const handleExceed: UploadProps['onExceed'] = (files: File[], index: number) => {
    const uploadInstance = uploadRefs.value[index];
    if (!uploadInstance) return;

    // 清空当前实例的文件
    uploadInstance.clearFiles();

    // 添加新文件
    const file = files[0] as UploadRawFile;
    file.uid = genFileId();
    uploadInstance.handleStart(file);
  };

  const handleSubmit = async () => {
    if (!formRef.value) return;

    try {
      await formRef.value.validate();
      const cloneFormData: FormData = cloneDeep(formData);
      cloneFormData.sysDictDataList = cloneFormData.sysDictDataList.map((item) => {
        return {
          ...item,
          dictCode: cloneFormData.dictCode,
        };
      });
      const codeSet = new Set();
      for (const item of cloneFormData.sysDictDataList) {
        if (codeSet.has(item.itemCode)) {
          ElMessage.warning(`字典项编码 "${item.itemCode}" 重复，请修改`);
          return;
        }
        codeSet.add(item.itemCode);
      }
      emit('submit', cloneFormData);
    } catch (err) {
      // 6. 校验失败
      console.warn('表单校验未通过', err);
    }
  };

  // 移动方法
  const moveDictItem = (index: number, direction: 'up' | 'down') => {
    const items = formData.sysDictDataList;
    if (direction === 'up' && index > 0) {
      // 交换位置
      [items[index - 1], items[index]] = [items[index], items[index - 1]];
    } else if (direction === 'down' && index < items.length - 1) {
      // 交换位置
      [items[index + 1], items[index]] = [items[index], items[index + 1]];
    }

    // 根据最新位置重新设置排序值
    items.forEach((item, idx) => {
      item.itemSort = idx + 1;
    });
  };

  const handleCancel = () => {
    emit('close');
  };

  // 暴露方法给父组件，例如重置表单
  defineExpose({
    resetForm: () => {
      formRef.value?.resetFields();
      formData.sysDictDataList = [
        {
          id: undefined,
          dictId: undefined,
          dictCode: '',
          itemCode: '',
          itemValue: '',
          itemSort: 1, // 默认排序值
          isDefault: 0,
          status: DictionaryStatus.disabled,
          imageUrl: '',
        },
      ];
    },
    getFormData: () => formData, // 允许父组件获取当前表单数据
  });
</script>

<style lang="scss" scoped>
  .add-dict-form {
    // padding-bottom: 40px;
    .el-select,
    .el-input-number {
      width: 100%;
    }
  }

  .dict-item-group {
    padding: 15px;
    border-radius: 4px;
    margin-bottom: 20px;
    background-color: #f0f2f5;
    position: relative;

    .dict-item-header {
      display: flex;
      justify-content: flex-end;
      align-items: center;
      margin-bottom: 10px;

      h4 {
        margin: 0;
        font-size: 16px;
      }
    }
  }

  .form-footer {
    position: sticky;
    bottom: 0;
    background: white;
    padding: 20px 0;
    z-index: 100;
    // box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.06);
    text-align: right;
  }

  .add-dict-form {
    height: calc(100vh - 120px); // 根据实际抽屉高度调整
    overflow-y: auto;
    padding-right: 10px;
    .el-select,
    .el-input-number {
      width: 100%;
    }
  }

  // 覆盖 el-upload 的样式，使其适应小图标场景
  :deep(.el-upload--picture-card) {
    width: 100px;
    height: 100px;
    line-height: 110px;
  }

  :deep(.el-upload-list--picture-card .el-upload-list__item) {
    width: 100px;
    height: 100px;
  }

  .subDictWrapper {
    display: flex;

    .dictItemsLabel {
      width: 30%;
      font-size: 14px;
      color: #606266;
      text-align: right;
      margin-right: 26px;
    }

    .subDictList {
      flex: 1;
    }
  }

  .dict-item-header {
    margin-bottom: 10px;

    .move-buttons {
      display: flex;
      align-items: center;
      justify-content: end;
      width: 100%;
      margin-right: auto;
      .el-button {
        padding: 5px;
        // margin-right: 8px;
      }
    }
  }

  .dialog-content {
    // width: 600px;
    // height: 600px;

    img {
      width: 100%;
      height: 100%;
    }
  }

  .add-text {
    margin-left: 10px;
  }
</style>
