package com.jwipc.supplier.logic.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.jwipc.constant.DelFlag;
import com.jwipc.constant.DictCode;
import com.jwipc.constant.EnableStatus;
import com.jwipc.exception.DaoException;
import com.jwipc.supplier.constant.*;
import com.jwipc.supplier.convert.*;
import com.jwipc.supplier.dto.*;
import com.jwipc.supplier.entity.*;
import com.jwipc.supplier.logic.RegisterLogic;
import com.jwipc.supplier.logic.SupplierLogic;
import com.jwipc.supplier.model.po.FieldDictPO;
import com.jwipc.supplier.model.po.SupplierTemplateFieldPO;
import com.jwipc.supplier.model.po.TemplateQuestionnairePO;
import com.jwipc.supplier.service.*;
import com.jwipc.sys.client.CompanyClient;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.FileClient;
import com.jwipc.sys.client.SysConfigClient;
import com.jwipc.sys.client.dto.CompanyDTO;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.client.dto.FileResposeCDTO;
import com.jwipc.sys.client.dto.ValidationRuleSettingInfoClientDTO;
import com.jwipc.sys.client.ValidationRuleSettingClient;
import com.jwipc.util.EncryptUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class RegisterLogicImpl implements RegisterLogic {
    private final ISupplierAgreementService supplierAgreementService;
    private final SupplierAgreementConvert supplierAgreementConvert;
    private final ISupplierTemplateService supplierTemplateService;
    private final ISupplierTemplateFieldRelationService supplierTemplateFieldRelationService;
    private final SupplierTemplateFieldConvert supplierTemplateFieldConvert;
    private final IQualificationTemplateService qualificationTemplateService;
    private final IQualificationTemplateItemService qualificationsTemplateItemService;
    private final ISupplierQualificationService supplierQualificationsService;
    private final SupplierQualificationConvert supplierQualificationsConvert;
    private final FileClient fileClient;
    private final DictClient dictClient;
    private final SysConfigClient sysConfigClient;
    private final ISupplierService supplierService;
    private final ISupplierQuestionnaireAnswerService supplierQuestionnaireAnswerService;
    private final SupplierTemplateQuestionnaireConvert templateQuestionnaireConvert;
    private final ISupplierExtensionService supplierExtensionService;
    private final ISupplierBankService supplierBankService;
    private final ISupplierContactsService supplierContactsService;
    private final SupplierBankConvert supplierBankConvert;
    private final SupplierContactsConvert supplierContactsConvert;
    private final SupplierQuestionnaireAnswerConvert supplierQuestionnaireAnswerConvert;
    private final ISupplierAgreementVersionService supplierAgreementVersionService;
    private final SupplierLogic supplierLogic;
    private final ISupplierFieldService supplierFieldService;
    private final ISupplierInvitaionService supplierInvitaionService;
    private final CompanyClient companyClient;
    private final IQualificationService qualificationService;
    private final ValidationRuleSettingClient validationRuleSettingClient;


    @Override
    public RegisterPageDTO renderRegisterPage(RegisterParamDTO registerParamDTO) {
        RegisterPageDTO pageDTO = new RegisterPageDTO();
        final SupplierAgreement agreement = supplierAgreementService.getOne(new LambdaQueryWrapper<SupplierAgreement>()
                .orderBy(true, false, SupplierAgreement::getAgreementVersion).last("limit 1"));
        final SupplierAgreementDTO agreementDTO = supplierAgreementConvert.entity2DTO(agreement);
        pageDTO.setAgreement(agreementDTO);
        String templateId = registerParamDTO.getTemplateId();
        final Integer type = registerParamDTO.getType();
        String supplierId = registerParamDTO.getSupplierId();
        //type等于0，表示此链接是用于生成供应商邀请链接
        if (templateId != null && type.equals(0)) {
            try {
                //需要判断是否是数字，如果是不需要解码
                if (StrUtil.isNotEmpty(templateId) && !StrUtil.isNumeric(templateId)) {
                    templateId = EncryptUtils.decrypt(templateId);
                }
                //如果模板传0，则用默认的default模板
                if ("0".equals(templateId)) {
                    final SupplierTemplate moduleTemplate = getDefaultTemplate();
                    templateId = String.valueOf(moduleTemplate.getId());
                }

                if (StrUtil.isNotEmpty(supplierId)) {
                    supplierId = EncryptUtils.decrypt(supplierId);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        pageDTO.setSupplierId(registerParamDTO.getSupplierId());
        pageDTO.setTemplateId(registerParamDTO.getTemplateId());
        final SupplierTemplate moduleTemplate = supplierTemplateService.getById(templateId);
        pageDTO.setEnableQuestionnaire(moduleTemplate.getEnableQuestionnaire());
        pageDTO.setTemplateId(String.valueOf(moduleTemplate.getId()));
        List<SupplierTemplateFieldPO> moduleTemplateFieldFormMapList =
                supplierTemplateFieldRelationService.selectByTemplate(
                        templateId,
                        DelFlag.NORMAL.getStatus());
        for (SupplierTemplateFieldPO e : moduleTemplateFieldFormMapList) {
            if (e.getFormControl() == TemplateFiledType.DICT.getType()) {
                final String sqlSentence = e.getSqlSentence();
                if (StringUtils.isNotEmpty(sqlSentence)) {
                    List<FieldDictPO> map = supplierTemplateFieldRelationService.selectDataBySql(sqlSentence);
                    e.setData(JSON.toJSONString(map));
                    e.setFieldLength(map.size());
                }
            }
        }

        List<SupplierTemplateFieldDTO> templateBaseFieldList = Lists.newArrayList();
        List<SupplierTemplateFieldDTO> templateTextFieldList = Lists.newArrayList();

        //关联表字段
        Map<String, String> templateFollowTable = new HashMap<>();
        // 待加载关联表【必填-表名称】
        Map<String, String> requiredTemplateFollowTable = new HashMap<>();

        //问卷调查字段
        Map<String, SupplierTemplateFieldDTO> questionnaireFieldList = new HashMap<>();
        //根据form_control判断字段属于哪种类型，1.基础字段 2.表格 3.问卷调查
        moduleTemplateFieldFormMapList.forEach(e -> {
            Integer formControl = e.getFormControl();
            final TemplateFiledType filedType = TemplateFiledType.forType(formControl);
            switch (filedType) {
                case BASIC:
                    //基础字段
                    //需要把fieldName从下划线变成驼峰
                    e.setFieldName(StrUtil.toCamelCase(e.getFieldName()));
                    templateBaseFieldList.add(supplierTemplateFieldConvert.po2DTO(e));
                    break;
                case ASSOCIATED:
                    String fieldType = e.getFieldType();
                    if (fieldType.equals("table")) {
                        //关联表
                        templateFollowTable.put(e.getFieldName(), e.getLabelName());
                        // 关联表必填
                        if (e.getRequired() == 1) {
                            requiredTemplateFollowTable.put(e.getFieldName(),
                                    StrUtil.isEmpty(e.getFieldAlias()) ? e.getLabelName() : e.getFieldAlias());
                        }
                        break;
                    } else if (fieldType.equals("varchar")) {
                        // 长文本
                        //需要把fieldName从下划线变成驼峰
                        e.setFieldName(StrUtil.toCamelCase(e.getFieldName()));
                        templateTextFieldList.add(supplierTemplateFieldConvert.po2DTO(e));
                        break;
                    }
                case NUMBER:
                    //数字
                    e.setFieldName(StrUtil.toCamelCase(e.getFieldName()));
                    templateBaseFieldList.add(supplierTemplateFieldConvert.po2DTO(e));
                    break;
                case AREA:
                case DICT:
                    //字典字段
                case DATE:
                    // 日期字段
                    //需要把fieldName从下划线变成驼峰
                    e.setFieldName(StrUtil.toCamelCase(e.getFieldName()));
                    templateBaseFieldList.add(supplierTemplateFieldConvert.po2DTO(e));
                    break;
                default:
            }
        });
        //直接把有required并且required=false的给排除掉
        pageDTO.setFieldList(new ArrayList<>(templateBaseFieldList));
        pageDTO.setQuestionnaireFieldList(questionnaireFieldList);
        pageDTO.setTextList(templateTextFieldList);
        pageDTO.setTemplateFollowTable(templateFollowTable);
        final String qualificationTemplateCode = moduleTemplate.getQualificationTemplateCode();
        final String templateQualificationVersion = moduleTemplate.getQualificationVersion();
        final QualificationTemplate qualificationTemplate = qualificationTemplateService.getOne(
                new LambdaQueryWrapper<QualificationTemplate>()
                        .eq(QualificationTemplate::getCode, qualificationTemplateCode)
                        .eq(QualificationTemplate::getVersion, templateQualificationVersion)
        );
        final List<QualificationTemplateItem> qualificationsTemplateItemList = qualificationsTemplateItemService.list(
                new LambdaQueryWrapper<QualificationTemplateItem>().eq(QualificationTemplateItem::getTemplateId,
                        qualificationTemplate.getId()));
        List<QualificationsItemRegisterDTO> qualificationsItemRegisterDTOS =
                supplierQualificationsConvert.entities2DTOS(
                        qualificationsTemplateItemList);
        //如果供应商id不是空的，需要获取供应商的资质数
        if (StrUtil.isNotEmpty(supplierId)) {
            final List<SupplierQualification> list = supplierQualificationsService.list(
                    new LambdaQueryWrapper<SupplierQualification>().eq(SupplierQualification::getSupplierId,
                            supplierId).eq(SupplierQualification::getState,
                            QualificationStatus.ENABLE.getStatus()));
            //需要把供应商上传的文件放到对应的数据上面
            for (QualificationsItemRegisterDTO qualificationsTemplateItem : qualificationsItemRegisterDTOS) {
                //需要清空fileId
                qualificationsTemplateItem.setFileId(null);
                if (StrUtil.isNotEmpty(qualificationsTemplateItem.getSimpleFileId())) {
                    final FileResposeCDTO fileResposeDTO = fileClient.getFileInfo(
                            Long.valueOf(qualificationsTemplateItem.getSimpleFileId()));
                    if (Objects.nonNull(fileResposeDTO)) {
                        qualificationsTemplateItem.setSimpleFileName(fileResposeDTO.getFileName());
                    }
                }
                for (SupplierQualification supplierQualifications : list) {
                    if (supplierQualifications.getQualificationCode().equals(qualificationsTemplateItem.getCode())) {
                        // 覆盖默认id为 数据资料id
                        qualificationsTemplateItem.setId(supplierQualifications.getId());
                        qualificationsTemplateItem.setQualificationNumber(
                                supplierQualifications.getQualificationNumber());
                        qualificationsTemplateItem.setAvailableStartDate(
                                supplierQualifications.getAvailableStartDate());
                        qualificationsTemplateItem.setAvailableEndDate(supplierQualifications.getAvailableEndDate());
                        // 实际上传文件
                        qualificationsTemplateItem.setFileId(supplierQualifications.getFileId());
                        final FileResposeCDTO fileInfo = fileClient.getFileInfo(
                                Long.valueOf(supplierQualifications.getFileId()));
                        qualificationsTemplateItem.setFileName(fileInfo.getFileName());
                    }
                }
            }
        }
        pageDTO.setQualifiList(qualificationsItemRegisterDTOS);
        final List<DictDTO> dicByType = dictClient.getDicByType(DictCode.SUPPLIER_REGISTER_TYPE.getCode());
        pageDTO.setQualifiTypeList(dicByType);
        if (StrUtil.isNotEmpty(supplierId)) {
            final Supplier supplier = supplierService.getById(supplierId);
            if (Objects.isNull(supplier)) {
                pageDTO.setErrorMsg("未找到该供应商");
                return pageDTO;
            }
            if (supplier.getSignUpThrough() == SignUpThrough.REGISTERED.getStatus()) {
                pageDTO.setErrorMsg("该供应商已注册!邀请链接已失效!");
                List<String> sysConfigKeys = Lists.newArrayList();
                sysConfigKeys.add(SysConfigKey.supplierRegisterErrorMsg.getCode());
                sysConfigKeys.add(SysConfigKey.supplierRegisterErrorImg.getCode());
                sysConfigKeys.add(SysConfigKey.supRegisterLogo.getCode());
                sysConfigKeys.add(SysConfigKey.supRegisterLogoDesc.getCode());
                sysConfigKeys.add(SysConfigKey.supRegisterDesc.getCode());
                final Map<String, String> map = sysConfigClient.getByKeyList(sysConfigKeys);
                pageDTO.setConfig(map);
                return pageDTO;
            }
            //需要把供应商的数据放到map中
            final Map<String, Object> stringObjectMap = BeanUtil.beanToMap(supplier);
            final List<SupplierExtension> list = supplierExtensionService.list(
                    new LambdaQueryWrapper<SupplierExtension>().eq(SupplierExtension::getSupplierId, supplierId));
            for (SupplierExtension supplierExtension : list) {
                stringObjectMap.put(supplierExtension.getExtensionKey(), supplierExtension.getExtensionValue());
            }
            pageDTO.setSupplier(stringObjectMap);
        }

        /**
         * 如果模板启用了问卷调查，则查找改模板的问卷调查题目
         */
        if (moduleTemplate.getEnableQuestionnaire() == EnableStatus.ENABLE.getStatus()) {
            //需要组装问卷内容
            final List<TemplateQuestionnairePO> templateQuestionnairePOS = supplierLogic.questionnaireAndItemByRelation(
                    templateId,
                    supplierId);
            if (StrUtil.isNotEmpty(supplierId)) {
                for (TemplateQuestionnairePO e : templateQuestionnairePOS) {
                    /**
                     * 如果供应商id有值，而查出来的list没有answerId。说明该问卷供应商并未新建过。则新增一条供应商问卷调查回复
                     */
                    if (e.getAnswerId() == null) {
                        final SupplierQuestionnaireAnswer answer = new SupplierQuestionnaireAnswer();
                        answer.setSupplierId(Long.valueOf(supplierId));
                        answer.setQuestionCode(e.getQuestionCode());
                        answer.setQuestionContent(e.getQuestionContent());
                        supplierQuestionnaireAnswerService.save(answer);
                        e.setAnswerId(answer.getId());
                    }
                }
            }
            List<TemplateQuestionnaireDTO> questionnaireList = templateQuestionnaireConvert.pos2DTOs(
                    templateQuestionnairePOS);
            pageDTO.setQuestionnaireList(questionnaireList);
        }
        // 注册页面，待加载必填关联表【表名称】
        Set<String> strings = requiredTemplateFollowTable.keySet();
        pageDTO.setRequiredTemplateFollowTable(StringUtils.join(strings, ","));
        // 注册页面，待加载必填关联表【表名称-中文】
        Collection<String> chinese = requiredTemplateFollowTable.values();
        pageDTO.setRequiredTemplateFollowTableChinese(StringUtils.join(chinese, ","));
        List<String> sysConfigKeys = Lists.newArrayList();
        sysConfigKeys.add(SysConfigKey.webUrlIco.getCode());
        sysConfigKeys.add(SysConfigKey.supRegisterLogo.getCode());
        sysConfigKeys.add(SysConfigKey.supRegisterLogoDesc.getCode());
        sysConfigKeys.add(SysConfigKey.supRegisterDesc.getCode());
        final Map<String, String> map = sysConfigClient.getByKeyList(sysConfigKeys);
        pageDTO.setConfig(map);
        pageDTO.setAgreeFlag(0);
        //如果供应商已经同意了协议
        if (StrUtil.isNotEmpty(supplierId)) {
            final SupplierAgreementVersion supplierAgreementVersion = supplierAgreementVersionService.getOne(
                    new LambdaQueryWrapper<SupplierAgreementVersion>().eq(SupplierAgreementVersion::getSupplierId,
                            supplierId), false);
            if (Objects.nonNull(supplierAgreementVersion)) {
                pageDTO.setAgreeFlag(1);
            }
        }
        //需要获取公司信息
        final List<CompanyDTO> companyDTOS = companyClient.getAll();
        for (CompanyDTO companyDTO : companyDTOS) {
            companyDTO.setCodeWithDesc("(" + companyDTO.getCompanyCode() + ")" + companyDTO.getCompanyName());
        }
        pageDTO.setCompanyList(companyDTOS);
        return pageDTO;
    }

    private SupplierTemplate getDefaultTemplate() {
        final SupplierTemplate moduleTemplate = supplierTemplateService.getOne(
                new LambdaQueryWrapper<SupplierTemplate>().eq(SupplierTemplate::getTemplateCode, "default"), false);
        if (Objects.isNull(moduleTemplate)) {
            throw new DaoException("默认模板不存在");
        }
        return moduleTemplate;
    }

    @Override
    public RegisterDictDataDTO registerDictData(SupplierRegisterQueryDTO query) {
        final Set<String> dictType = query.getDictTypeSet();
        RegisterDictDataDTO registerDictDataDTO = new RegisterDictDataDTO();
        if (dictType != null) {
            if (dictType.contains(StrUtil.toCamelCase(DictCode.EDUCATION.getCode()))) {//学历
                registerDictDataDTO.setEducation(dictClient.getDicByType(DictCode.EDUCATION.getCode()));
            }
            if (dictType.contains(StrUtil.toCamelCase(DictCode.SUPPLIER_ROLE_TYPE.getCode()))) {//供应商联系人
                registerDictDataDTO.setSupplierRoleType(dictClient.getDicByType(DictCode.SUPPLIER_ROLE_TYPE.getCode()));
            }
            if (dictType.contains(StrUtil.toCamelCase(DictCode.SUPPLIER_STAFF_TYPE.getCode()))) {//员工类型、各类员工数量
                registerDictDataDTO.setSupplierStaffType(
                        dictClient.getDicByType(DictCode.SUPPLIER_STAFF_TYPE.getCode()));
            }
        }
        return registerDictDataDTO;
    }

    @Override
    public void autoSave(RegisterAutoSaveDTO autoSaveDTO) {
        final String supplierId = autoSaveDTO.getSupplierId();
        checkSupplierInfo(autoSaveDTO.getFieldName(), autoSaveDTO.getFieldValue(), supplierId);
    }

    private void checkSupplierInfo(String fieldName, String fieldValue, Long supplierId) {
        final LambdaQueryWrapper<Supplier> queryWrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(supplierId)) {
            queryWrapper.ne(Supplier::getId, supplierId);
        }
        //供应商唯一性校验
        if (StrUtil.isEmpty(fieldName)
                || StrUtil.isEmpty(fieldValue)) {
            return;
        }
        final SupplierUniqueField supplierUniqueField = SupplierUniqueField.forValue(fieldName);
        if (Objects.isNull(supplierUniqueField)) {
            return;
        }
        switch (supplierUniqueField) {
            case supplierName -> {
                if (supplierService.count(queryWrapper.eq(Supplier::getSupplierName, fieldValue)) > 0) {
                    throw new DaoException("供应商名称已存在！");
                }
            }
            case shortName -> {
                if (supplierService.count(queryWrapper.eq(Supplier::getShortName, fieldValue)) > 0) {
                    throw new DaoException("供应商简称已存在！");
                }
            }
            case businessRegisterNo -> {
                if (supplierService.count(queryWrapper.eq(Supplier::getBusinessRegisterNo, fieldValue)) > 0) {
                    throw new DaoException("供应商注册码已存在！");
                }
            }
            case taxNo -> {
                if (supplierService.count(queryWrapper.eq(Supplier::getTaxNo, fieldValue)) > 0) {
                    throw new DaoException("供应商税码已存在！");
                }
            }
        }
    }

    private void checkSupplierInfo(String fieldName, String fieldValue, String supplierId) {
        Long supplierIdLong = null;
        if (!StrUtil.isEmpty(supplierId)) {
            final String decrypt = EncryptUtils.decrypt(supplierId);
            //需要对数据加密
            final Supplier supplier = supplierService.getById(decrypt);
            if (Objects.nonNull(supplier.getInfoState()) &&
                    supplier.getInfoState() == InformationStatus.REGISTRATION_COMPLETED.getValue()) {
                throw new DaoException("供应商已注册，不可更改信息！");
            }
            supplierIdLong = Long.valueOf(decrypt);
        }
        checkSupplierInfo(fieldName, fieldValue, supplierIdLong);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String followTableSave(RegisterSaveDTO followTable, Integer step) {
        final Map<String, String> supplier = followTable.getSupplier();
        //供应商主表，现在需要把提交的数据分成主表保存和扩展表保存
        List<String> tableColumns = supplierService.getTableStruct();
        List<SupplierExtension> supplierExtensions = new ArrayList<>();
        final Supplier supplier1 = BeanUtil.mapToBean(supplier, Supplier.class, true);

        String ecSupplierId = followTable.getSupplierId();
        final Long supplierId;
        final Long templateId;
        if (StrUtil.isNotEmpty(ecSupplierId)) {
            //这里需要单独用wrapper方式更新
            final UpdateWrapper<Supplier> supplierUpdateWrapper = new UpdateWrapper<>();
            if (Objects.nonNull(supplier)) {
                for (String s : supplier.keySet()) {
                    //需要把不在供应商主表的字段排除
                    if (tableColumns.contains(StrUtil.toUnderlineCase(s)) && !s.equals("id")) {
                        supplierUpdateWrapper.set(StrUtil.toUnderlineCase(s), supplier.get(s));
                    }
                }
            }
            supplierId = Long.valueOf(EncryptUtils.decrypt(ecSupplierId));
            supplierUpdateWrapper.set("sign_up_through", InformationStatus.NEW.getValue());
            supplierUpdateWrapper.set("info_state", step);
            supplierUpdateWrapper.set("update_time", LocalDateTime.now());
            supplierUpdateWrapper.eq("id", supplierId);
            final Supplier byId = supplierService.getById(supplierId);
            templateId = byId.getTemplateId();
            if (step == InformationStatus.STEP_ONE.getValue()) {
                //需要把之前的数据删除掉
                if (Objects.nonNull(byId)) {
                    supplierExtensionService.remove(
                            new LambdaQueryWrapper<SupplierExtension>().eq(SupplierExtension::getSupplierId,
                                    supplierId));
                    supplierFieldService.remove(
                            new LambdaQueryWrapper<SupplierField>().eq(SupplierField::getSupplierId, supplierId));
                }
            }
            final SupplierAgreementVersion supplierAgreementVersion = supplierAgreementVersionService.getOne(
                    new LambdaQueryWrapper<SupplierAgreementVersion>().eq(SupplierAgreementVersion::getSupplierId,
                            supplierId), false);
            supplierAgreementVersion.setAgreementVersion(followTable.getAgreementVersion());
            supplierAgreementVersionService.updateById(supplierAgreementVersion);
            supplierService.update(supplierUpdateWrapper);
        } else {
            //自主注册就是用默认模板
            supplier1.setInfoState(step);
            final SupplierTemplate defaultTemplate = getDefaultTemplate();
            templateId = defaultTemplate.getId();
            supplier1.setTemplateId(templateId);
            supplier1.setRegisterType(RegisterType.SELF.getType());
            supplierService.save(supplier1);
            supplierId = supplier1.getId();
            SupplierAgreementVersion supplierAgreementVersion = new SupplierAgreementVersion();
            supplierAgreementVersion.setSupplierId(supplierId);
            supplierAgreementVersion.setAgreementVersion(followTable.getAgreementVersion());
            supplierAgreementVersion.setCreateTime(LocalDateTime.now());
            supplierAgreementVersionService.save(supplierAgreementVersion);
            //需要插入供应商邀请数据
            SupplierInvitaion supplierInvitaion = new SupplierInvitaion();
            supplierInvitaion.setTemplateId(templateId);
            supplierInvitaion.setSupplierId(supplierId);
            supplierInvitaion.setCreateTime(LocalDateTime.now());
            supplierInvitaion.setShortName(supplier1.getShortName());
            supplierInvitaion.setEmail(supplier1.getEmail());
            supplierInvitaionService.save(supplierInvitaion);
        }
        final List<SupplierTemplateFieldPO> supplierTemplateFieldPOS =
                supplierTemplateFieldRelationService.selectByTemplate(
                        String.valueOf(templateId), DelFlag.NORMAL.getStatus());
        if (step == InformationStatus.STEP_ONE.getValue()) {
            //需要把模板的字段信息保存一份，要不然后面模板修改了这个地方就出现问题
            List<SupplierField> supplierFields = Lists.newArrayList();
            for (SupplierTemplateFieldPO fieldPO : supplierTemplateFieldPOS) {
                SupplierField supplierField = new SupplierField();
                supplierField.setFieldCode(fieldPO.getFieldName());
                supplierField.setFieldAlias(
                        StrUtil.isNotEmpty(fieldPO.getFieldAlias()) ? fieldPO.getFieldAlias() : fieldPO.getLabelName());
                supplierField.setFieldSort(fieldPO.getFieldSort());
                supplierField.setFieldType(fieldPO.getFieldType());
                supplierField.setSqlSentence(fieldPO.getSqlSentence());
                supplierField.setValidateStr(fieldPO.getValidateStr());
                supplierField.setRequired(fieldPO.getRequired());
                supplierField.setFormControl(fieldPO.getFormControl());
                supplierField.setSupplierId(supplierId);
                supplierFields.add(supplierField);
            }
            if (CollUtil.isNotEmpty(supplierFields)) {
                supplierFieldService.saveBatch(supplierFields);
            }
            for (String s : supplier.keySet()) {
                checkSupplierInfo(s, supplier.get(s), supplierId);
            }
        }
        //需要组装成code-标题
        final Map<String, String> fieldNamTitleMap = supplierTemplateFieldPOS.stream()
                .collect(Collectors.toMap(a -> StrUtil.toCamelCase(a.getFieldName()), a -> {
                    if (StrUtil.isNotEmpty(a.getFieldAlias())) {
                        return a.getFieldAlias();
                    } else {
                        return a.getLabelName();
                    }
                }));
        if (CollUtil.isNotEmpty(supplier)) {
            for (String key : supplier.keySet()) {
                if (!tableColumns.contains(StrUtil.toUnderlineCase(key))) {
                    //这个地方的字段是供应商主表中
                    SupplierExtension supplierExtension = new SupplierExtension();
                    supplierExtension.setExtensionKey(key);
                    final String label = fieldNamTitleMap.get(key);
                    supplierExtension.setExtensionLabel(label);
                    supplierExtension.setExtensionValue(supplier.get(key));
                    supplierExtension.setSupplierId(supplierId);
                    supplierExtensions.add(supplierExtension);
                }
            }
        }
        if (CollUtil.isNotEmpty(supplierExtensions)) {
            supplierExtensionService.saveBatch(supplierExtensions, 300);
        }
        final List<SupplierBankDTO> bankList = followTable.getBankList();
        if (CollUtil.isNotEmpty(bankList)) {
            List<SupplierBank> supplierBanks = supplierBankConvert.dtos2Entities(bankList);
            supplierBanks.forEach(a -> a.setSupplierId(supplierId));
            if (CollUtil.isNotEmpty(supplierBanks)) {
                supplierBankService.saveOrUpdateBatch(supplierBanks);
            }
        }
        final List<SupplierContactsDTO> contactsList = followTable.getContactsList();
        if (CollUtil.isNotEmpty(contactsList)) {
            List<SupplierContacts> supplierContacts = supplierContactsConvert.dtos2Entities(contactsList);
            supplierContacts.forEach(a -> a.setSupplierId(supplierId));
            final List<SupplierContacts> list = supplierContacts.stream()
                    .filter(a -> StrUtil.isNotEmpty(a.getContactsType())).toList();
            if (CollUtil.isNotEmpty(list)) {
                supplierContactsService.saveOrUpdateBatch(list);
            }
        }

        final List<SupplierQualificationBaseDTO> attachmentList = followTable.getAttachmentList();
        if (CollUtil.isNotEmpty(attachmentList)) {
            supplierQualificationsService.remove(
                    new LambdaQueryWrapper<>(SupplierQualification.class).eq(SupplierQualification::getSupplierId,
                            supplierId));
            List<SupplierQualification> supplierQualifications = supplierQualificationsConvert.dtos2Entities(
                    attachmentList);
            final Set<String> collect = supplierQualifications.stream().map(SupplierQualification::getQualificationCode)
                    .collect(Collectors.toSet());
            final List<Qualification> list = qualificationService.list(
                    new LambdaQueryWrapper<>(Qualification.class).in(Qualification::getCode, collect));
            final Map<String, Qualification> qualificationMap = list.stream()
                    .collect(Collectors.toMap(a -> a.getCode(), a -> a));
            supplierQualifications.forEach(a -> {
                a.setSupplierId(supplierId);
                final Qualification qualification = qualificationMap.get(a.getQualificationCode());
                a.setVersion(qualification.getVersion());
                a.setScene(qualification.getScene());
                a.setCreateTime(LocalDateTime.now());
            });
            if (CollUtil.isNotEmpty(supplierQualifications)) {
                supplierQualificationsService.saveOrUpdateBatch(supplierQualifications);
            }
        }
        final List<SupplierQuestionnaireAnswerDTO> questionnaireAnswer = followTable.getQuestionnaireAnswer();
        if (CollUtil.isNotEmpty(questionnaireAnswer)) {
            for (SupplierQuestionnaireAnswerDTO supplierQuestionnaireAnswerDTO : questionnaireAnswer) {
                //需要把supplierId解密
                final String supplierId1 = supplierQuestionnaireAnswerDTO.getSupplierId();
                if (!StrUtil.isNumeric(supplierId1)) {
                    supplierQuestionnaireAnswerDTO.setSupplierId(EncryptUtils.decrypt(supplierId1));
                }
            }
            List<SupplierQuestionnaireAnswer> supplierQuestionnaireAnswers =
                    supplierQuestionnaireAnswerConvert.dtos2Entities(
                            questionnaireAnswer);
            supplierQuestionnaireAnswers.forEach(a -> a.setSupplierId(supplierId));
            if (CollUtil.isNotEmpty(supplierQuestionnaireAnswers)) {
                supplierQuestionnaireAnswerService.updateBatchById(supplierQuestionnaireAnswers);
            }
        }
        return EncryptUtils.encrypt(String.valueOf(supplierId));
    }

    @Override
    public RegisterBaseDTO followTableByTemplate(SupplierRegisterQueryDTO query) {
        final RegisterBaseDTO followTable = new RegisterBaseDTO();
        final Long supplierId;
        if (!StrUtil.isNumeric(query.getSupplierId())) {
            supplierId = Long.valueOf(EncryptUtils.decrypt(query.getSupplierId()));
        } else {
            supplierId = Long.valueOf(query.getSupplierId());
        }

        final Set<String> templateField = CollUtil.isEmpty(
                query.getTemplateTableSet()) ? Sets.newHashSet() : query.getTemplateTableSet();
        if (supplierId != null) {
            //供应商银行
            if (templateField.contains(SupplierFollowTableTypeEnum.Bank.getTableName())) {
                final List<SupplierBank> list = supplierBankService.list(
                        new LambdaQueryWrapper<SupplierBank>().eq(SupplierBank::getSupplierId, supplierId));
                followTable.setBankList(supplierBankConvert.entities2DTOs(list));
            }
            //供应商员工
            if (templateField.contains(SupplierFollowTableTypeEnum.SupplierContact.getTableName())) {
                final List<SupplierContacts> supplierContacts = supplierContactsService.list(
                        new LambdaQueryWrapper<SupplierContacts>().eq(SupplierContacts::getSupplierId, supplierId));
                followTable.setContactsList(supplierContactsConvert.entities2DTOs(supplierContacts));
            }
        }
        return followTable;
    }

    @Override
    public void agreement(String id, String agreementVersion) {
        final Long supplierId = Long.valueOf(EncryptUtils.decrypt(id));
        final SupplierAgreementVersion version = supplierAgreementVersionService.getOne(
                new LambdaQueryWrapper<SupplierAgreementVersion>().eq(SupplierAgreementVersion::getSupplierId,
                        supplierId), false);
        if (version == null) {
            final SupplierAgreementVersion agreementVersionInsert = new SupplierAgreementVersion();
            agreementVersionInsert.setSupplierId(supplierId);
            agreementVersionInsert.setAgreementVersion(agreementVersion);
            agreementVersionInsert.setCreateTime(LocalDateTime.now());
            supplierAgreementVersionService.save(agreementVersionInsert);
        }
    }

    @Override
    public void followTableRemove(Long id, String tableType) {
        SupplierFollowTableTypeEnum type = SupplierFollowTableTypeEnum.getValue(tableType);
        if (Objects.isNull(type)) {
            new DaoException("参数不正确");
        }
        switch (type) {
            case Bank -> supplierBankService.removeById(id);
            case SupplierContact -> supplierContactsService.removeById(id);
        }
    }

    @Override
    public List<ValidationRuleSettingInfoClientDTO> getFieldValidationList(String templateId, Integer type) {
        return validationRuleSettingClient.getFieldValidationList(templateId, type);
    }
}