<script lang="ts" setup>
import { ref, watch, reactive, onMounted, h, computed, nextTick } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue'; // 确保导入
import VxeUI from 'vxe-table';
import { useRequest } from 'alova/client';
import { getDictionaryMethod, cpMedicinesMethod } from '@/request/api/dictionary.api';
import { branchMethod } from '@/request/api/system.api';
import { systemCpEditMethod, getAllSupplierMethod, getConditioningSchemeDetailMethod } from '@/request/api/care.api';
import { UploadIFile } from '@/request/api/follow.api';
import type { SystemItemModel } from '@/model/care.model';
import SearchableSelect from '@/components/SearchableSelect.vue';
import type { UploadFile } from 'ant-design-vue/es/upload/interface';
import type { FormInstance } from 'ant-design-vue';
import Derivation from '@/service/Derivation.vue';
type SystemModel = Partial<SystemItemModel>;
const props = defineProps<{ data: SystemModel; institutionId: string | number }>();
const formRef = ref<FormInstance>();
const typeOptionsLoading = ref<boolean>(false);
const typeOptions = ref<{ label: string; value: string }[]>([]);

// 统一提升消息提示层级，避免被弹窗遮挡
message.config({ zIndex: 10000, top: 80, maxCount: 3, duration: 2 } as any);

const supplierOptions = ref<{ label: string; value: string }[]>([]);

const isRequired = ref<boolean>(true);
// 使用单位
const unitOptions = [
  { label: '袋', value: '袋' },
  { label: '包', value: '包' },
  { label: '贴', value: '贴' },
  { label: '次', value: '次' },
];
const herbList = ref<any[]>([]);

// 获取所有的机构
const branch = ref<any[]>([]);
const { loading: branchLoading } = useRequest(branchMethod).onSuccess(({ data }) => {
  const to = (data?: any[]): any[] => {
    return Array.isArray(data)
      ? data.map((item) => {
        return {
          ...item,
          value: item.id,
          key: item.id.toString(),
          children: to(item.children),
        };
      })
      : [];
  };
  branch.value = to(data);
});
// 表单字段与后端类型并非完全一致（存在 string/number 混用），统一放宽类型避免 TS 误报
const form = reactive<any>({
  institutionName: '',
  conditioningProgramType: '',
  frequencyType: '',
  frequencyMeasure: undefined as number | undefined,
  offlineDuration: '',
  sellType: '',// 商品类型 1-实体商品 2-线下服务 3-线上权益
  conditioningProgramSupplierId: '',
  institutionId: '',
  cpDynamicPricingRule: [
    { min: '', max: '', priceType: '', price: '' },
    { min: '', max: '', priceType: '', price: '' },
  ],
  pricingType: '0',
  cpFixedPricingRule: {
    unitPrice: '',
    pricingUnit: '',
    convertDose: '',
    convertUnit: '',
  },
  cpPatientMatchRule: {
    sex: '', // 性别
    age: '', // 年龄
    diagnoseDiseaseNames: [], // 疾病
    diagnoseSyndromeNames: [], // 证型
    constitutionGroupNames: [], // 体质
    willillStateNames: [], // 欲病状态
    tabooCrowds: [], // 禁忌
  },
  cpMedicines: [{ name: '', dosage: '', id: '' }],
  isDelivery: null,
  effect: '', // 功效
  photo: '', // 商品图片
  itemImgFirst: '', // 操作图片
  itemVideoFirst: '', // 操作视频
  attrFirst: '', // 特色
  attrSeventh: '', //使用注意
  attrSixth: '', // 疗程说明
  attrFifth: '', // 操作方法
  attrFourth: '', // 用法
  attrThird: '', // 制法
  status: '0', // 状态
  isForWrap: null, // 是否服务包项目
  isForInfer: null, // 是否调理方案项目
  attrEighth: '', // 购买链接
  attrNinth: '', // 跳转类型
});

const checkedList = ref<string[]>(['1']); // 默认选中第一个

// 建议频率相关字段
const suggestedFrequencyUnit = ref<string>(''); // 建议频率单位


// 添加推导逻辑编辑状态
const isDerivationModalOpen = ref(false);

const rules: any = {
  name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
  conditioningProgramType: [{ required: true, message: '请选择方案类型', trigger: 'change' }],
  offlineDuration: [{ required: true, message: '请输入服务所需时间', trigger: 'blur' }],
  institutionId: [
    {
      trigger: 'blur',
      validator: async (_rule: any, value: any) => {
        // 如果推导逻辑弹窗打开，跳过验证
        if (isDerivationModalOpen.value) return Promise.resolve();
        if (!value) return Promise.reject('请选择机构名称');
        return Promise.resolve();
      },
    },
  ],
  photo: [{ required: true, message: '请上传商品图片', trigger: 'change' }],
  isDelivery: [
    {
      trigger: 'change',
      validator: async (_rule: any, value: any) => {
        // 如果只选择了调理方案项目（包含 '2' 但不包含 '1'），配送不必填
        if (checkedList.value.includes('2') && !checkedList.value.includes('1')) {
          return Promise.resolve();
        }
        // 项目应用含有服务包项目或商品类型是实体商品时，配送必填
        if ((checkedList.value.includes('1') || form.sellType === '1') && !value) {
          return Promise.reject('请选择配送方式');
        }
        return Promise.resolve();
      },
    },
  ],
};
const showMiniProgramCode = ref<boolean>(false);
const showBuyLink = ref<boolean>(false);
// 判断是否为小程序码类型
const isMiniProgramCodeType = computed(() => {
  return form.attrNinth === 'miniprogram';
});
watch(
  () => form.attrNinth,
  (newVal) => {
    if (newVal && newVal === 'URL') {
      // 购买链接显示不必填  小程序码隐藏
      showMiniProgramCode.value = false;
      showBuyLink.value = true;
    } else if (newVal && newVal === 'miniprogram') {
      // 跳转类型是小程序码 小程序码显示并且必上传  购买链接显示不必填
      showMiniProgramCode.value = true;
      showBuyLink.value = true;
    } else {
      // 跳转类型是其他类型 小程序码隐藏 购买链接隐藏 目前是这样处理  后期如果有其他类型再做处理
      showMiniProgramCode.value = false;
      showBuyLink.value = false;
    }
  }
);
const supplierArr = ref<any[]>([]);

// 商品类型相关显示控制
// 实体商品：itemsList 和 system 类型都需要显示配送选项
const showDelivery = computed(() => {
  return form.sellType === '1';
});

// 判断配送是否必填（显示红色星号）
const isDeliveryRequired = computed(() => {
  // 如果只选择了调理方案项目，不必填
  if (checkedList.value.includes('2') && !checkedList.value.includes('1')) {
    return false;
  }
  // 项目应用含有服务包项目或商品类型是实体商品时，必填
  return checkedList.value.includes('1') || form.sellType === '1';
});

// 线下服务：itemsList 和 system 类型都需要“服务所需时间”
const showServiceRequiredTime = computed(() => {
  return form.sellType === '2';
});

// 获取所有的供应商
async function getSupplier(params: any) {
  supplierOptions.value = [];
  const res = (await getAllSupplierMethod(params)) as any[];
  if (Array.isArray(res) && res.length > 0) {
    supplierArr.value = res;
    supplierOptions.value = res.map((item: any) => ({
      label: item.name,
      value: item.id,
    }));
  }
}
watch(
  [() => form.conditioningProgramType, () => form.institutionId, () => form.conditioningProgramSupplierId],
  ([newType, newInstitutionId, newSupplierId]) => {
    getSupplier({
      conditioningProgramTypes: newType ? [newType] : form.conditioningProgramType ? [form.conditioningProgramType] : [],
      collaborateDeptId: newInstitutionId ? newInstitutionId : form.institutionId ? form.institutionId : '',
      conditioningProgramSupplierId: newSupplierId ? newSupplierId : form.conditioningProgramSupplierId ? form.conditioningProgramSupplierId : '',
    });
  },
  { immediate: true }
);

function addHerb() {
  if (!form.cpMedicines) {
    form.cpMedicines = [];
  }
  form.cpMedicines.push({ name: '', dosage: '', id: '' });
}
function removeHerb(idx: number | string) {
  if (form.cpMedicines) {
    form.cpMedicines.splice(Number(idx), 1);
  }
}

function cancel() {
  VxeUI.modal.close(`add-items-modal`);
}
function doSubmit() {
  // 手动验证方案类型
  // if (!form.conditioningProgramType) {
  //   message.error('请选择方案类型');
  //   return;
  // }

  // 自定义验证：检查项目应用是否已选择
  if (!checkedList.value || checkedList.value.length === 0) {
    message.error('请选择项目应用');
    return;
  }
  form.isForWrap = checkedList.value.includes('1') ? 'Y' : null;
  form.isForInfer = checkedList.value.includes('2') ? 'Y' : null;
  // 服务包项目相关必填
  if ((form.addType === 'itemsList' && checkedList.value.includes('1')) || form.addType === 'system') {
    // 计价规则
    if (!form.pricingType) {
      message.error('请选择计价规则');
      return;
    }
    // 计价规则相关字段校验
    if (form.pricingType === '0') {
      const { unitPrice, pricingUnit, convertDose, convertUnit } = form.cpFixedPricingRule || {};
      const allFilled =
        unitPrice !== '' && unitPrice !== null && unitPrice !== undefined && pricingUnit && convertDose !== '' && convertDose !== null && convertDose !== undefined && convertUnit;
      if (!allFilled) {
        message.error('请将单价、计价单位、相当于、使用单位全部填写');
        return;
      }
      delete form.cpDynamicPricingRule;
    } else if (form.pricingType === '1') {
      const rule1 = form.cpDynamicPricingRule[0] || {};
      const rule2 = form.cpDynamicPricingRule[1] || {};
      const allFilled1 = rule1.min && typeof rule1.priceType !== 'undefined' && rule1.price;
      const allFilled2 = rule2.max && typeof rule2.priceType !== 'undefined' && rule2.price;
      rule1.max = 0;
      rule2.min = 0;
      if (!(allFilled1 && allFilled2)) {
        message.error('请将按穴位/经络/部位的所有计价字段全部填写');
        return;
      }
      // 按穴位模式：清空一口价数据
      delete form.cpFixedPricingRule;
    }
    // 供应商
    // if (form.addType === 'itemsList' && checkedList.value.includes('1')) {
    //   // if (!form.conditioningProgramSupplierId) {
    //   //   message.error('请选择供应商');
    //   //   return;
    //   // }
    // } else
    // 商品类型相关校验（itemsList 和 system 都需要）
    if (form.addType === 'itemsList' || form.addType === 'system') {
      if (!form.sellType) {
        message.error('请选择商品类型');
        return;
      }
      // 建议频率必填：每X天X(单位)
      if (!form.frequencyType || !form.frequencyMeasure || !suggestedFrequencyUnit.value) {
        message.error('请填写建议频率');
        return;
      }
      // 线下服务：服务所需时间必填
      // if (form.sellType === '2' && !form.offlineDuration) {
      //   message.error('请输入服务所需时间');
      //   return;
      // }
      // 实体商品：配送必填（itemsList 和 system 类型都需要）
      // if (form.sellType === '1' && (!deliverArr.value || deliverArr.value.length === 0)) {
      //   message.error('请选择配送方式');
      //   return;
      // }
    }
  } else if (form.addType === 'itemsList') {
    // 计价规则非必填时，做全填/全空校验
    if (form.pricingType === '0') {
      const { unitPrice, pricingUnit, convertDose, convertUnit } = form.cpFixedPricingRule || {};
      const allFilled =
        unitPrice !== '' && unitPrice !== null && unitPrice !== undefined && pricingUnit && convertDose !== '' && convertDose !== null && convertDose !== undefined && convertUnit;
      const allEmpty = !unitPrice && !pricingUnit && !convertDose && !convertUnit;
      if (!(allFilled || allEmpty)) {
        message.error('单价、计价单位、相当于、使用单位要么全部填写，要么全部为空');
        return;
      }
      // 一口价模式：清空按穴位数据
      if (allFilled) {
        delete form.cpDynamicPricingRule;
      }
    } else if (form.pricingType === '1') {
      const rule1 = form.cpDynamicPricingRule[0] || {};
      const rule2 = form.cpDynamicPricingRule[1] || {};
      const allFilled1 = rule1.min && typeof rule1.priceType !== 'undefined' && rule1.price;
      const allEmpty1 = !rule1.min && (typeof rule1.priceType === 'undefined' || rule1.priceType === '' || rule1.priceType === null) && !rule1.price;
      const allFilled2 = rule2.max && typeof rule2.priceType !== 'undefined' && rule2.price;
      const allEmpty2 = !rule2.max && (typeof rule2.priceType === 'undefined' || rule2.priceType === '' || rule2.priceType === null) && !rule2.price;
      if (!((allFilled1 && allFilled2) || (allEmpty1 && allEmpty2))) {
        message.error('按穴位/经络/部位的所有计价字段要么全部填写，要么全部为空');
        return;
      }
      // 按穴位模式：清空一口价数据
      if (allFilled1 && allFilled2) {
        delete form.cpFixedPricingRule;
      }
    }
  }
  // 调理方案项目相关必填
  if (form.addType === 'itemsList' && checkedList.value.includes('2')) {
    if (!hasDerivationLogic.value) {
      message.error('请设置推导逻辑');
      return;
    }
  }

  // 购买链接与跳转类型联动校验
  if (form.addType === 'itemsList') {

    // 有购买链接则必须选择跳转类型
    const hasBuyUrl = !!(form.attrEighth && String(form.attrEighth).trim());
    if (hasBuyUrl && !form.attrNinth) {
      message.error('请选择跳转类型');
      return;
    }
    // 如果选择了小程序码类型，类型是小程序码  小程序码必填 链接可填
    if (form.attrNinth === 'miniprogram' && miniProgramCodeList.value.length === 0) {
      message.error('请上传小程序码');
      return;
    }
  }

  // 商品图片必填
  // if (!fileList.value || fileList.value.length === 0) {
  //   message.error('请上传商品图片');
  //   return;
  // }

  formRef.value?.validate().then(() => {
    form.photo = fileList.value[0]?.response?.url || fileList.value[0]?.url || '';
    form.itemImgFirst = optionsList.value[0]?.response?.url || optionsList.value[0]?.url || '';
    form.attrTen = miniProgramCodeList.value[0]?.response?.url || miniProgramCodeList.value[0]?.url || '';
    // 合并推导逻辑数据到表单数据中
    if (hasDerivationLogic.value && derivationData.value.cpPatientMatchRule) {
      form.cpPatientMatchRule = { ...derivationData.value.cpPatientMatchRule };
    }
    if ((props.data as any).isType === 'itemsList') {
      delete form.id;
    }
    submit(form);
  });
}
// 获取方案类型
async function getConditioningProgramType() {
  typeOptionsLoading.value = true;
  try {
    const res = await getDictionaryMethod('condition_type');
    if (res?.length > 0) {
      typeOptions.value = res; // 直接使用返回的数据
    }
  } catch (error: any) {
    message.error(error.message);
  } finally {
    typeOptionsLoading.value = false;
  }
}
const jumpTypeOptionsLoading = ref(false);
const jumpTypeOptions = ref<{ label: string; value: string }[]>([]);
// 获取跳转类型
async function getJumpType() {
  jumpTypeOptionsLoading.value = true;
  try {
    const res = await getDictionaryMethod('fdhb_cpbuy_type');
    if (res?.length > 0) {
      jumpTypeOptions.value = res;
    }
  } catch (error: any) {
    message.error(error.message);
  } finally {
    jumpTypeOptionsLoading.value = false;
  }
}

// 处理下拉框点击事件
function handleSelectClick() {
  // 如果选项为空且不在加载中，尝试重新获取数据
  if (typeOptions.value.length === 0 && !typeOptionsLoading.value) {
    getConditioningProgramType();
  }
}

onMounted(async () => {
  const deptId = localStorage.getItem('deptId');
  if (props.data.addType === 'system' && deptId) {
    form.institutionId = deptId;
  }
  if (props.data.addType === 'system') {
    isRequired.value = false;
  }
  form.addType = props.data.addType;
  // 新增（itemsList / system）默认选中实体商品
  if (
    (form.addType === 'itemsList' || form.addType === 'system') &&
    !(props.data as any).id &&
    !(props.data as any).sourceId &&
    !form.sellType
  ) {
    form.sellType = '1';
  }
  if ((props.data as any).id || (props.data as any).sourceId) {
    const res: any = await getConditioningSchemeDetailMethod(props.data as any);
    const checked: string[] = [];
    if (res.isForWrap === 'Y') checked.push('1');
    if (res.isForInfer === 'Y') checked.push('2');
    checkedList.value = checked.length > 0 ? checked : ['1', '2'];
    Object.assign(form, res);
    suggestedFrequencyUnit.value = res.convertUnit; // 建议频率使用单位
    form.cpMedicines = (res.cpMedicines ?? []).map((item: any) => ({
      name: item.name || item.herbName || item.medicineName || '',
      dosage: item.dosage,
      id: item.id,
    }));

    // 处理推导逻辑数据回填
    if (res.cpPatientMatchRule) {
      derivationData.value = { cpPatientMatchRule: res.cpPatientMatchRule };
      hasDerivationLogic.value = true;
    }

    fileList.value = res.photo
      ? [
        {
          uid: '-1',
          name: 'image.png',
          status: 'done',
          url: res.photo,
          thumbUrl: res.photo,
        },
      ]
      : [];
    optionsList.value = res.itemImgFirst
      ? [
        {
          uid: '-1',
          name: 'image.png',
          status: 'done',
          url: res.itemImgFirst,
          thumbUrl: res.itemImgFirst,
        },
      ]
      : [];
    miniProgramCodeList.value = res.attrTen
      ? [
        {
          uid: '-1',
          name: 'image.png',
          status: 'done',
          url: res.attrTen,
          thumbUrl: res.attrTen,
        },
      ]
      : [];
    // 处理视频数据
    if (res.itemVideoFirst) {
      videoFileList.value = [
        {
          uid: '-1',
          name: '操作视频',
          status: 'done',
          url: res.itemVideoFirst,
          response: { url: res.itemVideoFirst },
        },
      ];
    }
    if ((props.data as any).isType === 'itemsList' && (props.data as any).sourceId) {
      form.sourceId = form.id;
      // form.institutionId = '';
      // 确保 institutionId 是简单值，不是对象格式
      const instId = props.data.institutionId;
      form.institutionId = (instId && typeof instId === 'object' && 'value' in instId ? (instId as any).value : instId) as any;
      form.institutionName = props.data.institutionName;
    }
  }
  // 获取方案类型
  getConditioningProgramType();
  // 获取跳转类型
  getJumpType();
});
const emits = defineEmits<{
  submit: [data?: SystemItemModel];
  addSubmit: [data?: SystemItemModel];
}>();
const { send: submit } = useRequest((data: any) => systemCpEditMethod(data)!, {
  immediate: false,
}).onSuccess(() => {
  emits('submit');
});

const visible = ref<boolean>(false);
const setVisible = (value: boolean): void => {
  visible.value = value;
};
const previewImg = ref<string>('');
const uploadProps = reactive({ showRemoveIcon: true });
// 商品图片
const fileList = ref<UploadFile[]>([]);
// 操作图片
const optionsList = ref<UploadFile[]>([]);
// 小程序码
const miniProgramCodeList = ref<UploadFile[]>([]);

// 上传组件只更新 fileList，不会自动写回 form.photo；需要手动同步以便表单校验能立刻通过/清除提示
watch(
  fileList,
  (list) => {
    const url = list?.[0]?.response?.url || list?.[0]?.url || '';
    form.photo = url;
    if (url) {
      // 上传成功后立即清除“商品图片必填”的校验提示
      formRef.value?.clearValidate?.(['photo']);
    }
  },
  { deep: true }
);
// 安全挂载弹层，避免 document 不可用或被父层遮挡
function getSafePopupContainer(triggerNode?: HTMLElement) {
  try {
    // @ts-ignore
    if (typeof document !== 'undefined' && document?.body) return document.body;
  } catch (e) {
    // ignore
  }
  return (triggerNode?.parentNode as HTMLElement) || undefined;
}

// 统一用 change 处理（避免 @select 改值导致面板被打断）
function onInstitutionChange(val: string | number | { value: string | number; label?: any } | undefined) {
  // 处理 labelInValue 格式：如果是对象，提取 value；否则直接使用
  if (val && typeof val === 'object' && 'value' in val) {
    form.institutionId = val.value as any;
  } else {
    form.institutionId = val as any;
  }
}
// 预览图片
const handlePreview = async (file: UploadFile) => {
  previewImg.value = file.response?.url ?? file.thumbUrl;
  visible.value = true;
};

function customUpload(e: any) {
  UploadIFile(e.file)
    .then((res) => {
      // 调用实例的成功方法通知组件该文件上传成功
      e.onSuccess(res, e);
    })
    .catch((err) => {
      // 调用实例的失败方法通知组件该文件上传失败
      e.onError(err);
    });
}
// 视频上传相关
const accept = 'video/mp4,video/avi,video/mov,video/webm';
const maxSize = 100 * 1024 * 1024; // 100MB

const videoUrl = ref('');
const uploading = ref(false);
const progress = ref(0);
const videoFileList = ref<UploadFile[]>([]);

// 供应商改为可选，不再必填
const supplierRules = computed(() => {
  return [];
});

// 上传前校验
function beforeVideoUpload(file: File) {
  const isValidType = accept.split(',').includes(file.type);
  if (!isValidType) {
    message.error('仅支持mp4、avi、mov、webm格式视频');
    return false;
  }

  const isValidSize = file.size <= maxSize;
  if (!isValidSize) {
    message.error('视频大小不能超过100MB');
    return false;
  }

  return true;
}

// 视频预览
function handleVideoPreview(file: UploadFile) {
  const videoUrl = file.response?.url || file.url || form.itemVideoFirst;
  if (videoUrl) {
    VxeUI.modal.open({
      title: '视频预览',
      width: 800,
      height: 600,
      escClosable: true,
      destroyOnClose: true,
      slots: {
        default() {
          return h(
            'div',
            {
              style: {
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                height: '100%',
              },
            },
            [
              h('video', {
                src: videoUrl,
                controls: true,
                style: {
                  maxWidth: '100%',
                  maxHeight: '100%',
                  borderRadius: '8px',
                },
              }),
            ]
          );
        },
      },
    });
  }
}

// 删除视频
function removeVideo() {
  form.itemVideoFirst = '';
  videoFileList.value = [];
  message.success('视频已删除');
}

// 自定义上传
function customVideoRequest(e: any) {
  const { file, onSuccess, onError, onProgress } = e;

  // 验证文件
  if (!beforeVideoUpload(file)) {
    onError(new Error('文件验证失败'));
    return;
  }

  uploading.value = true;
  progress.value = 0;

  // 模拟上传进度
  const progressInterval = setInterval(() => {
    if (progress.value < 90) {
      progress.value += Math.random() * 10;
      onProgress({ percent: progress.value });
    }
  }, 200);

  // 上传文件
  UploadIFile(file)
    .then((res: any) => {
      clearInterval(progressInterval);
      progress.value = 100;
      onProgress({ percent: 100 });

      // 设置视频URL
      form.itemVideoFirst = res?.url || res?.data?.url;

      // 更新文件列表
      videoFileList.value = [
        {
          uid: file.uid,
          name: file.name,
          status: 'done',
          url: form.itemVideoFirst,
          response: res,
        },
      ];

      onSuccess(res, e);
      uploading.value = false;
      message.success('视频上传成功');
    })
    .catch((err) => {
      clearInterval(progressInterval);
      uploading.value = false;
      progress.value = 0;
      onError(err);
      message.error('视频上传失败，请重试');
    });
}

// 视频上传状态变化
function handleVideoChange(info: any) {
  const { file, fileList } = info;

  if (file.status === 'uploading') {
    uploading.value = true;
  } else if (file.status === 'done') {
    uploading.value = false;
    videoFileList.value = fileList;
  } else if (file.status === 'error') {
    uploading.value = false;
    message.error('视频上传失败');
  }
}

watch(
  () => form.pricingType,
  (val) => {
    if (val === '0') {
      // 一口价模式：确保 cpFixedPricingRule 存在
      if (!form.cpFixedPricingRule) {
        form.cpFixedPricingRule = {
          unitPrice: '',
          pricingUnit: '',
          convertDose: '',
          convertUnit: '',
        };
      }
      // 一口价模式：建议频率单位与一口价单位保持一致
      if (form.cpFixedPricingRule?.convertUnit) {
        suggestedFrequencyUnit.value = form.cpFixedPricingRule.convertUnit;
      } else {
        suggestedFrequencyUnit.value = '';
      }
    } else if (val === '1') {
      // 按穴位模式：确保 cpDynamicPricingRule 存在
      if (!form.cpDynamicPricingRule) {
        form.cpDynamicPricingRule = [
          { min: '', max: '', priceType: '', price: '' },
          { min: '', max: '', priceType: '', price: '' },
        ];
      }
      // 按穴位模式：建议频率单位默认为"次"
      suggestedFrequencyUnit.value = '次';
    }
  }
);

// 监听一口价单位变化，同步到建议频率单位
watch(
  () => form.cpFixedPricingRule?.convertUnit,
  (newVal) => {
    if (form.pricingType === '0') {
      // 当 convertUnit 有值时同步，清空时也同步清空
      suggestedFrequencyUnit.value = newVal || '';
    }
  }
);

// 监听建议频率单位变化，回写到一口价使用单位（保证双向一致）
watch(
  () => suggestedFrequencyUnit.value,
  (newVal) => {
    if (form.pricingType === '0' && form.cpFixedPricingRule && newVal) {
      form.cpFixedPricingRule.convertUnit = newVal;
    }
  }
);

// 监听商品类型变化，控制配送默认值
watch(
  () => form.sellType,
  (newVal) => {
    if (newVal === '1') {
      // 实体商品：默认支持配送（itemsList / system 都一样）
      // 但如果只选择了调理方案项目，配送不是必填，不设置默认值，让用户自己选择
      if (!(checkedList.value.includes('2') && !checkedList.value.includes('1'))) {
        form.isDelivery = 'Y';
      }
    } else {
      // 其他类型：清空配送
      form.isDelivery = null;
    }
  }
);

// 监听项目应用变化，当只选择调理方案项目时，自动设置为一口价
watch(
  () => checkedList.value,
  (newVal) => {
    // 如果只选择了调理方案项目（包含 '2' 但不包含 '1'），自动设置为一口价
    if (newVal.includes('2') && !newVal.includes('1')) {
      form.pricingType = '0';
      // 如果只选择调理方案项目，配送不是必填，清空默认值让用户自己选择
      if (form.sellType === '1') {
        form.isDelivery = null;
      }
    } else if (form.sellType === '1' && !form.isDelivery) {
      // 如果从只选择调理方案项目变为其他情况，且是实体商品，恢复默认值
      form.isDelivery = 'Y';
    }
  }
);
function getConditioningProgramSupplier() {
  // 供应商改为可选，不做额外强制联动
}

// 处理配送选项点击，允许取消选择
function handleDeliveryClick(value: string) {
  // 如果点击的是已选中的选项，则取消选择
  if (form.isDelivery === value) {
    form.isDelivery = null;
  } else {
    form.isDelivery = value;
  }
}
// 项目应用数据
const plainOptions = [
  { id: '1', name: '服务包项目' },
  { id: '2', name: '调理方案项目' },
];

// 推导逻辑
const hasDerivationLogic = ref(false); // 添加推导逻辑状态跟踪
const derivationData = ref<any>({});
// 判断推导逻辑内容是否为空
const isDerivationEmpty = computed(() => {
  const rule = derivationData.value.cpPatientMatchRule;
  if (!rule) return true;
  // 检查所有字段都为空或未填写
  const fields = ['sex', 'age', 'diagnoseDiseaseNames', 'diagnoseSyndromeNames', 'constitutionGroupNames', 'willillStateNames', 'tabooCrowds'];
  return fields.every((key) => {
    const val = rule[key];
    if (Array.isArray(val)) return val.length === 0;
    return !val;
  });
});
function handleDerivation() {
  // 设置推导逻辑弹窗打开状态
  isDerivationModalOpen.value = true;

  VxeUI.modal.open({
    title: `推导逻辑`,
    height: 750,
    width: 750,
    escClosable: true,
    destroyOnClose: true,
    id: `derivation-modal`,
    remember: true,
    storage: true,
    onClose: () => {
      // 弹窗关闭时清除验证状态并重置状态
      isDerivationModalOpen.value = false;
      nextTick(() => {
        formRef.value?.clearValidate(['institutionId', 'conditioningProgramSupplierId']);
      });
    },
    slots: {
      default() {
        return h(Derivation, {
          data: {
            ...(props.data as any),
            // 传递当前的推导逻辑数据
            cpPatientMatchRule: derivationData.value.cpPatientMatchRule || form.cpPatientMatchRule,
            checkedList: checkedList.value,
          } as any,
          onSubmit: (data: any) => {
            derivationData.value = data;
            hasDerivationLogic.value = true; // 设置推导逻辑已编辑

            // 重置状态并清除验证状态
            isDerivationModalOpen.value = false;
            nextTick(() => {
              formRef.value?.clearValidate(['institutionId', 'conditioningProgramSupplierId']);
            });
          },
          onCancel: () => {
            // 取消时重置状态并清除验证状态
            isDerivationModalOpen.value = false;
            nextTick(() => {
              formRef.value?.clearValidate(['institutionId', 'conditioningProgramSupplierId']);
            });
          },
        });
      },
    },
  });
}
</script>

<template>
  <div class="form-container">
    <a-form ref="formRef" :model="form" :rules="rules" layout="horizontal">
      <a-form-item label="项目名称：" name="name">
        <a-input v-model:value="form.name" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="方案类型：" name="conditioningProgramType" style="width: 100%" required>
        <vxe-select v-model="form.conditioningProgramType" :options="typeOptions" placeholder="请选择方案类型" clearable
          filterable transfer empty-text="暂无数据" @focus="handleSelectClick" style="width: 100%" />
      </a-form-item>
      <a-form-item label="项目应用：" required v-if="form.addType === 'itemsList'">
        <a-checkbox-group v-model:value="checkedList">
          <a-checkbox v-for="option in plainOptions" :key="option.id" :value="option.id">
            {{ option.name }}
          </a-checkbox>
        </a-checkbox-group>
      </a-form-item>
      <a-form-item label="商品类型：" v-if="form.addType === 'itemsList' || form.addType === 'system'" required>
        <a-radio-group v-model:value="form.sellType">
          <a-radio value="1">实体商品</a-radio>
          <a-radio value="2">线下服务</a-radio>
          <a-radio value="3">线上权益</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="计价规则：" name="pricingType" :required="checkedList.includes('1') || (checkedList.includes('2') && !checkedList.includes('1'))">
        <a-radio-group v-model:value="form.pricingType">
          <a-radio value="0">一口价</a-radio>
          <a-radio value="1" v-if="!checkedList.includes('2')">按穴位/经络/部位</a-radio>
        </a-radio-group>
      </a-form-item>
      <div class="price-row" v-if="form.pricingType === '0' && form.cpFixedPricingRule">
        <span class="label">单价：</span>
        <a-input v-model:value="form.cpFixedPricingRule.unitPrice" placeholder="请输入" style="width: 100px" />
        <span style="margin: 0 8px">元</span>

        <span class="label" style="margin-left: 32px">计价单位：</span>
        <a-input v-model:value="form.cpFixedPricingRule.pricingUnit" placeholder="请输入" style="width: 100px" />

        <span style="margin-left: 32px">相当于</span>
        <a-input v-model:value="form.cpFixedPricingRule.convertDose" placeholder="请输入"
          style="width: 100px; margin-left: 8px" />
        <vxe-select v-model="form.cpFixedPricingRule.convertUnit" :options="unitOptions" placeholder="请选择" clearable
          transfer style="width: 100px; margin-left: 8px" />

        <span style="color: #aaa; margin-left: 8px">(使用单位)</span>
      </div>
      <div v-if="form.pricingType === '1'" class="per-rule">
        <div class="price-row">
          <span>计价1：</span>
          <span class="flex items-center">当"穴位/经络/部位" ≤
            <a-input placeholder="请输入" class="w-20 ml-2 mr-2" v-model:value="form.cpDynamicPricingRule[0].min"
              @change="() => (form.cpDynamicPricingRule[1].max = form.cpDynamicPricingRule[0].min)" />个时，</span>
          <vxe-select v-model="form.cpDynamicPricingRule[0].priceType" :options="[
            { label: '单价', value: 0, priceType: 0 },
            { label: '一口价', value: 1, priceType: 1 },
          ]" placeholder="请选择" clearable transfer style="width: 100px; margin: 0 4px" />
          <span>=</span>
          <a-input v-model:value="form.cpDynamicPricingRule[0].price" style="width: 80px; margin: 0 4px"
            placeholder="请输入" />
          <span>元</span>
        </div>
        <div class="price-row">
          <span>计价2：</span>
          <span class="flex items-center">当"穴位/经络/部位" &gt; <a-input placeholder="请输入" class="w-20 ml-2 mr-2"
              v-model:value="form.cpDynamicPricingRule[1].max" disabled />个时，</span>
          <vxe-select v-model="form.cpDynamicPricingRule[1].priceType" :options="[
            { label: '单价', value: 0, priceType: 0 },
            { label: '一口价', value: 1, priceType: 1 },
          ]" placeholder="请选择" clearable transfer style="width: 100px; margin: 0 4px" />
          <span>=</span>
          <a-input v-model:value="form.cpDynamicPricingRule[1].price" style="width: 80px; margin: 0 4px"
            placeholder="请输入" />
          <span>元</span>
        </div>
      </div>
      <a-form-item label="建议频率：" v-if="form.addType === 'itemsList' || form.addType === 'system'" required>
        <div class="suggested-frequency-row">
          <span>每</span>
          <a-input v-model:value="form.frequencyType" placeholder="请输入" style="width: 100px; margin: 0 8px" />
          <span>天</span>
          <a-input v-model:value="form.frequencyMeasure" placeholder="请输入" style="width: 100px; margin: 0 8px" />
          <vxe-select v-model="suggestedFrequencyUnit" :options="unitOptions" placeholder="请选择"
            :clearable="form.pricingType !== '0'" transfer style="width: 100px; margin-left: 8px" />
        </div>
      </a-form-item>
      <a-form-item label="服务所需时间："
      name="offlineDuration"
        v-if="(form.addType === 'itemsList' || form.addType === 'system') && showServiceRequiredTime" required>
        <a-input v-model:value="form.offlineDuration" placeholder="请输入" style="width: 200px" />
        <span style="margin-left: 8px">分钟</span>
      </a-form-item>


      <a-form-item label="组成：">
        <div class="herb-list">
          <template v-for="(herb, idx) in form.cpMedicines" :key="herb.id">
            <div class="herb-item">
              <button class="herb-remove" v-if="form?.cpMedicines?.length > 1" @click="removeHerb(idx)"
                type="button">×</button>
              <!-- <RemoteSelect :load="cpMedicinesMethod" key-prop="name" v-model:value="herb.name" /> -->
              <SearchableSelect v-model="herb.name" :options="herbList" placeholder="请选择" value-key="name"
                label-key="name" key-key="id" :fetch-options="cpMedicinesMethod" style="width: 150px"
                :allow-custom-input="true" />
              <a-input v-model:value="herb.dosage" class="herb-dosage" placeholder="剂量" />
              <span>g</span>
            </div>
          </template>
          <button style="margin-left: 8px" @click="addHerb" type="button">+</button>
        </div>
      </a-form-item>
      <a-form-item label="特色：" v-if="form.addType === 'itemsList'">
        <textarea v-model="form.attrFirst" placeholder="请输入" rows="3"
          style="width: 100%; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; resize: vertical; font-family: inherit" />
      </a-form-item>
      <a-form-item label="功效：">
        <a-input v-model:value="form.effect" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="制法：" v-if="form.addType === 'itemsList'">
        <a-input v-model:value="form.attrThird" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="用法：" v-if="form.addType === 'itemsList'">
        <a-input v-model:value="form.attrFourth" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="操作方法：" v-if="form.addType === 'itemsList'">
        <textarea v-model="form.attrFifth" placeholder="请输入" rows="3"
          style="width: 100%; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; resize: vertical; font-family: inherit" />
      </a-form-item>

      <div class="image-row">
        <a-form-item label="操作图片：" class="image-form-item" v-if="form.addType === 'itemsList'">
          <a-upload :showUploadList="uploadProps" v-model:file-list="optionsList" list-type="picture-card"
            @preview="handlePreview" :maxCount="1" :customRequest="customUpload">
            <div v-if="optionsList.length < 1">
              <PlusOutlined />
              <div style="margin-top: 8px">上传</div>
            </div>
          </a-upload>
        </a-form-item>
        <a-form-item label="商品图片：" class="image-form-item" name="photo" required>
          <a-upload :showUploadList="uploadProps" v-model:file-list="fileList" list-type="picture-card"
            @preview="handlePreview" :maxCount="1" :customRequest="customUpload">
            <div v-if="fileList.length < 1">
              <PlusOutlined />
              <div style="margin-top: 8px">上传</div>
            </div>
          </a-upload>
        </a-form-item>
      </div>
      <a-form-item label="操作视频：" class="image-form-item" v-if="form.addType === 'itemsList'">
        <div class="video-upload-wrapper">
          <div class="video-upload-container">
            <a-upload :showUploadList="false" :custom-request="customVideoRequest" :max-count="1" :multiple="false"
              :before-upload="beforeVideoUpload" @change="handleVideoChange" :file-list="videoFileList"
              accept="video/mp4,video/avi,video/mov,video/webm">
              <div v-if="!form.itemVideoFirst && !uploading" class="video-upload-btn">
                <PlusOutlined />
                <div style="margin-top: 8px">上传视频</div>
                <div class="video-upload-tip">mp4/avi/mov/webm<br />最大100MB</div>
              </div>

              <!-- 上传中状态 -->
              <div v-else-if="uploading" class="video-uploading">
                <div class="upload-progress">
                  <a-progress :percent="progress" :show-info="false" size="small" stroke-color="#1890ff" />
                  <div class="upload-text">上传中... {{ Math.round(progress) }}%</div>
                </div>
              </div>

              <!-- 视频预览 -->
              <div v-else class="video-preview-container">
                <div class="video-thumbnail">
                  <video :src="form.itemVideoFirst" preload="metadata" class="video-preview" />
                  <div class="video-overlay">
                    <a-button type="primary" size="small" @click.stop="
                      handleVideoPreview({
                        uid: 'video-preview',
                        name: '操作视频',
                        url: form.itemVideoFirst,
                      })
                      ">
                      预览
                    </a-button>
                    <a-button danger size="small" @click.stop="removeVideo"> 删除 </a-button>
                  </div>
                </div>
                <!-- <div class="video-info">
                  <div class="video-name">操作视频</div>
                  <div class="video-size">已上传</div>
                </div> -->
              </div>
            </a-upload>
          </div>
        </div>
      </a-form-item>
      <a-form-item label="疗程说明：" v-if="form.addType === 'itemsList'">
        <textarea v-model="form.attrSixth" placeholder="请输入" rows="3"
          style="width: 100%; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; resize: vertical; font-family: inherit" />
      </a-form-item>
      <a-form-item label="使用注意：" v-if="form.addType === 'itemsList'">
        <textarea v-model="form.attrSeventh" placeholder="请输入" rows="3"
          style="width: 100%; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; resize: vertical; font-family: inherit" />
      </a-form-item>
      <a-form-item label="推导逻辑：" v-if="form.addType === 'itemsList'" :required="checkedList.includes('2')">
        <button @click="handleDerivation" v-if="!hasDerivationLogic || isDerivationEmpty">编辑</button>
        <div v-else @click="handleDerivation" style="cursor: pointer">
          <div v-if="derivationData.cpPatientMatchRule" class="derivation-container">
            <div v-if="derivationData.cpPatientMatchRule.sex" class="derivation-item">
              <span class="derivation-label">性别限制：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.sex }}</span>
            </div>
            <div v-if="derivationData.cpPatientMatchRule.age" class="derivation-item">
              <span class="derivation-label">年龄限制：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.age }}</span>
            </div>
            <div
              v-if="derivationData.cpPatientMatchRule.diagnoseDiseaseNames && derivationData.cpPatientMatchRule.diagnoseDiseaseNames.length > 0"
              class="derivation-item">
              <span class="derivation-label">专病：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.diagnoseDiseaseNames.join('、')
                }}</span>
            </div>
            <div
              v-if="derivationData.cpPatientMatchRule.diagnoseSyndromeNames && derivationData.cpPatientMatchRule.diagnoseSyndromeNames.length > 0"
              class="derivation-item">
              <span class="derivation-label">证型：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.diagnoseSyndromeNames.join('、')
                }}</span>
            </div>
            <div
              v-if="derivationData.cpPatientMatchRule.constitutionGroupNames && derivationData.cpPatientMatchRule.constitutionGroupNames.length > 0"
              class="derivation-item">
              <span class="derivation-label">体质：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.constitutionGroupNames.join('、')
                }}</span>
            </div>
            <div
              v-if="derivationData.cpPatientMatchRule.willillStateNames && derivationData.cpPatientMatchRule.willillStateNames.length > 0"
              class="derivation-item">
              <span class="derivation-label">欲病状态：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.willillStateNames.join('、')
                }}</span>
            </div>
            <div
              v-if="derivationData.cpPatientMatchRule.tabooCrowds && derivationData.cpPatientMatchRule.tabooCrowds.length > 0"
              class="derivation-item">
              <span class="derivation-label">禁忌人群：</span>
              <span class="derivation-content">{{ derivationData.cpPatientMatchRule.tabooCrowds.join('、') }}</span>
            </div>
          </div>
        </div>
      </a-form-item>
      <!-- 跳转类型 -->
      <a-form-item label="跳转类型：" v-if="form.addType === 'itemsList'" style="width: 100%">
        <Vxe-select v-model="form.attrNinth" :options="jumpTypeOptions" placeholder="请选择" clearable transfer
          style="width: 100%" />
      </a-form-item>
      <!-- 购买链接 -->
      <a-form-item label="购买链接：" v-if="form.addType === 'itemsList' && showBuyLink">
        <a-input v-model:value="form.attrEighth" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="小程序码：" class="image-form-item" v-if="form.addType === 'itemsList' && showMiniProgramCode"
        :required="isMiniProgramCodeType">
        <a-upload :showUploadList="uploadProps" v-model:file-list="miniProgramCodeList" list-type="picture-card"
          @preview="handlePreview" :maxCount="1" :customRequest="customUpload">
          <div v-if="miniProgramCodeList.length < 1">
            <PlusOutlined />
            <div style="margin-top: 8px">上传</div>
          </div>
        </a-upload>
      </a-form-item>
      <!-- 机构名称 -->
      <a-form-item label="机构名称：" v-if="form?.addType === 'itemsList'" required name="institutionId">
        <a-tree-select :disabled="form.addType === 'itemsList' && !!form.sourceId" v-model:value="form.institutionId"
          style="width: 100%" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto', zIndex: 4000 }"
          :dropdownMatchSelectWidth="false" :getPopupContainer="getSafePopupContainer" placeholder="请选择" allow-clear
          tree-default-expand-all :tree-data="branch" :loading="branchLoading"
          @change="onInstitutionChange"></a-tree-select>
      </a-form-item>
      <a-form-item label="供应商：" name="conditioningProgramSupplierId" :rules="supplierRules" style="width: 100%">
        <a-select v-model:value="form.conditioningProgramSupplierId" :options="supplierOptions" placeholder="请选择"
          allow-clear show-search :getPopupContainer="getSafePopupContainer" :dropdownMatchSelectWidth="false"
          :dropdownStyle="{ zIndex: 5000 }" style="width: 100%" @change="getConditioningProgramSupplier"
          not-found-content="暂无数据" />
      </a-form-item>
      <a-form-item  name="isDelivery" v-if="showDelivery">
      
         
          <span> <span v-if="isDeliveryRequired" style="color: #ff4d4f">* </span>配送：</span>
      
        <a-radio-group :value="form.isDelivery">
          <a-radio value="Y" @click="handleDeliveryClick('Y')">支持</a-radio>
          <a-radio value="N" @click="handleDeliveryClick('N')">不支持</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="启用状态：" name="status" v-if="form.addType === 'itemsList'" required>
        <a-radio-group v-model:value="form.status">
          <a-radio value="0">启用</a-radio>
          <a-radio value="1">停用</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-image :width="200" :style="{ display: 'none' }" :preview="{
        visible,
        onVisibleChange: setVisible,
      }" :src="previewImg" />
      <video :src="videoUrl" controls v-if="videoUrl" style="width: 100%; max-width: 500px; border-radius: 6px"
        preload="metadata" />
      <div class="form-actions-center">
        <a-button @click="cancel">取消</a-button>
        <a-button type="primary" style="background: #faad14; border: none" @click="doSubmit">确定</a-button>
      </div>
    </a-form>
  </div>
</template>

<style scoped>
.form-container {
  width: 95%;
  margin: 0 auto;
  padding: 10px 0px 0 0;
  display: flex;
  flex-direction: column;
  /* max-height: 80vh; */
}

.per-rule {
  margin-bottom: 16px;
}

.price-row {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
}

.suggested-frequency-row {
  display: flex;
  align-items: center;
}

.label {
  font-weight: 500;
  color: #222;
  margin-right: 8px;
}

.herb-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.herb-item {
  position: relative;
  display: flex;
  align-items: center;
  margin-right: 8px;
  margin-bottom: 8px;
  padding-left: 16px;
}

.herb-dosage {
  width: 70px;
  font-size: 14px;
  margin-right: 10px;
}

.herb-remove {
  position: absolute;
  left: 0;
  top: 0;
  background: #fff;
  border: none;
  color: #ff4d4f;
  font-size: 14px;
  cursor: pointer;
  line-height: 1;
  width: 16px;
  height: 16px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.form-actions-center {
  display: flex;
  justify-content: center;
  gap: 16px;
  position: sticky;
  bottom: 0;
  background: #fff;
  padding: 12px 0;
}

.form-container .ant-form {
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.slider-section {
  margin-bottom: 16px;
}

.slider-labels {
  display: flex;
  justify-content: space-between;
  width: 200px;
  margin-left: 230px;
  margin-bottom: 4px;
  font-weight: 500;
  color: #222;
}

.slider-row {
  display: flex;
  align-items: center;
}

.slider-desc {
  color: #222;
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.slider-value {
  margin-left: 16px;
  color: #faad14;
  font-weight: bold;
}

.upload-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  background: #fafafa;
  cursor: pointer;
  transition: border-color 0.3s;
  width: 100px;
}

.upload-btn:hover {
  border-color: #1890ff;
  background: #f0f7ff;
}

.upload-btn .anticon {
  font-size: 16px;
  color: #1890ff;
}

.upload-btn .upload-text {
  margin-top: 8px;
  color: #666;
  font-size: 15px;
}

.video-preview {
  border-radius: 6px;
  background: #000;
  width: 120px !important;
  height: 100px !important;
}

.video-preview video {
  border-radius: 6px;
  background: #000;
  width: 120px;
  height: 100px;
}

.video-preview .ant-btn-link {
  padding: 0;
  font-size: 14px;
  color: #ff4d4f;
}

.image-row {
  display: flex;
  gap: 32px;
  align-items: flex-start;
  margin-bottom: 16px;
}

.image-form-item {
  flex: 1;
  margin-bottom: 0 !important;
}

.image-form-item .ant-upload-picture-card-wrapper {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.derivation-item {
  display: flex;
  align-items: center;
  min-width: 200px;
  max-width: 300px;
  padding: 6px 12px;
  background: #f5f5f5;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
}

.derivation-label {
  font-weight: 500;
  color: #222;
  margin-right: 8px;
  white-space: nowrap;
  font-size: 13px;
}

.derivation-content {
  color: #555;
  font-size: 13px;
  flex: 1;
  word-break: break-all;
}

.derivation-container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
}

.video-upload-wrapper {
  display: flex;
  align-items: flex-start;
}

.video-upload-container {
  position: relative;
  width: 130px;
  height: 130px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  background: #fafafa;
  cursor: pointer;
  transition: all 0.3s ease;
  overflow: hidden;
  margin-bottom: 20px;
}

.video-upload-container:hover {
  border-color: #1890ff;
  background: #f0f7ff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
}

.video-upload-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px 12px;
  text-align: center;
}

.video-upload-btn .anticon {
  font-size: 20px;
  color: #1890ff;
  margin-bottom: 6px;
}

.video-upload-tip {
  font-size: 11px;
  color: #999;
  margin-top: 6px;
  line-height: 1.3;
}

.video-uploading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
  backdrop-filter: blur(2px);
}

.upload-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 90%;
  max-width: 160px;
}

.upload-text {
  font-size: 12px;
  color: #1890ff;
  font-weight: 500;
  text-align: center;
}

.video-preview-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 10px;
  background: #fafafa;
  border-radius: 8px;
}

.video-thumbnail {
  position: relative;
  width: 100%;
  height: 100px;
  border-radius: 6px;
  overflow: hidden;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8px;
}

.video-thumbnail .video-preview {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.video-preview-container:hover .video-overlay {
  opacity: 1;
}

.video-overlay .ant-btn {
  background: rgba(255, 255, 255, 0.95);
  border: none;
  color: #333;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 4px;
  transition: all 0.3s ease;
  min-width: 40px;
  height: 28px;
  line-height: 1.2;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

.video-overlay .ant-btn:hover {
  background: rgba(255, 255, 255, 1);
  transform: scale(1.05);
}

.video-overlay .ant-btn-danger {
  background: rgba(255, 77, 79, 0.95);
  color: #fff;
}

.video-overlay .ant-btn-danger:hover {
  background: rgba(255, 77, 79, 1);
}

.video-info {
  text-align: center;
  font-size: 11px;
  color: #666;
}

.video-name {
  font-weight: 500;
  color: #333;
  margin-bottom: 2px;
}

.video-size {
  color: #999;
  font-size: 10px;
}
</style>
<style>
/* 提升 AntD Select 下拉层级，避免被弹窗/遮罩遮挡 */
.ant-select-dropdown {
  z-index: 5000 !important;
}
</style>
