package com.yeejoin.amos.boot.module.jg.biz.edit.process.equip;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.entity.TzsBaseEntity;
import com.yeejoin.amos.boot.module.common.api.dao.EsEquipmentDao;
import com.yeejoin.amos.boot.module.common.api.entity.ESEquipmentInfo;
import com.yeejoin.amos.boot.module.common.api.enums.CylinderTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.jg.api.dto.FieldChangeMeta;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistrationManage;
import com.yeejoin.amos.boot.module.jg.biz.edit.esUpdate.service.EsUpdateService;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.biz.DefaultBizDataChangeHandler;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.biz.strategy.IBizDataChangeHandleStrategy;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.equip.strategy.HandleResult;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.equip.strategy.IEquipChangeDataProcessStrategy;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgRegisterInfoServiceImpl;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquCodeTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.yeejoin.amos.boot.module.jg.api.enums.CertificateStatusEnum.YIDENGJI;

/**
 * 单个维护设备-策略实现类
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class SingleEquipChangeProcess implements IEquipChangeDataProcessStrategy {


    private final CommonEquipDataProcessService commonEquipDataProcessService;

    private final EsUpdateService esUpdateService;

    private final RestHighLevelClient restHighLevelClient;

    private final EsEquipmentDao esEquipmentDao;
    private final IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoServiceImpl;


    @Override
    public HandleResult handle(Map<String, Object> changeData, String record) {
        JSONObject changeJson = new JSONObject(changeData);
        List<FieldChangeMeta> allChangeColumns = new ArrayList<>();

        IdxBizJgUseInfo useInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getUseInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgUseInfo>().eq(IdxBizJgUseInfo::getRecord, record));
        IdxBizJgUseInfo useInfoNew = BeanUtil.copyProperties(useInfoOld, IdxBizJgUseInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, useInfoNew);
        useInfoNew.setSequenceNbr(useInfoOld.getSequenceNbr());
        commonEquipDataProcessService.setNameByCode2UseInfo(useInfoNew);

        IdxBizJgRegisterInfo registerInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgRegisterInfoService().getOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, record));
        IdxBizJgRegisterInfo registerInfoNew = BeanUtil.copyProperties(registerInfoOld, IdxBizJgRegisterInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, registerInfoNew);
        registerInfoNew.setSequenceNbr(registerInfoOld.getSequenceNbr());

        if (!ValidationUtil.isEmpty(registerInfoOld.getUseOrgCode())) {
            JgUseRegistrationManage jgUseRegistrationManage = commonEquipDataProcessService.getJgUseRegistrationManageService().lambdaQuery()
                    .eq(JgUseRegistrationManage::getUseRegistrationCode, registerInfoOld.getUseOrgCode())
                    .eq(JgUseRegistrationManage::getIsDelete,0)
                    .eq(JgUseRegistrationManage::getCertificateStatus,YIDENGJI.getName())
                    .select(JgUseRegistrationManage::getSequenceNbr, JgUseRegistrationManage::getReceiveCompanyCode).one();
            useInfoNew.setReceiveCompanyCode(jgUseRegistrationManage.getReceiveCompanyCode());
        }

        // 历史有证设备检验（台套类设备+气瓶）
        beforeCheckForUseOrgCode(useInfoOld, registerInfoNew);

        IdxBizJgFactoryInfo factoryInfoOld = commonEquipDataProcessService.getJgFactoryInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgFactoryInfo>().eq(IdxBizJgFactoryInfo::getRecord, record));
        IdxBizJgFactoryInfo factoryInfoNew = BeanUtil.copyProperties(factoryInfoOld, IdxBizJgFactoryInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, factoryInfoNew);
        factoryInfoNew.setSequenceNbr(factoryInfoOld.getSequenceNbr());

        beforeCheckForEquCode(factoryInfoOld, registerInfoNew);

        IdxBizJgDesignInfo designInfoOld = commonEquipDataProcessService.getIdxBizJgDesignInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgDesignInfo>().eq(IdxBizJgDesignInfo::getRecord, record));
        IdxBizJgDesignInfo designInfoNew = BeanUtil.copyProperties(designInfoOld, IdxBizJgDesignInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, designInfoNew);
        designInfoNew.setSequenceNbr(designInfoOld.getSequenceNbr());

        IdxBizJgOtherInfo otherInfoOld = commonEquipDataProcessService.getIdxBizJgOtherInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgOtherInfo>().eq(IdxBizJgOtherInfo::getRecord, record));
        IdxBizJgOtherInfo otherInfoNew = BeanUtil.copyProperties(otherInfoOld, IdxBizJgOtherInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, otherInfoNew);
        otherInfoNew.setSequenceNbr(otherInfoOld.getSequenceNbr());

        IdxBizJgSupervisionInfo idxBizJgSupervisionInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgSupervisionInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgSupervisionInfo>().eq(IdxBizJgSupervisionInfo::getRecord, record));
        IdxBizJgSupervisionInfo idxBizJgSupervisionInfoNew = BeanUtil.copyProperties(idxBizJgSupervisionInfoOld, IdxBizJgSupervisionInfo.class);
        CommonEquipDataProcessService.castMap2Bean(changeJson, idxBizJgSupervisionInfoNew);
        idxBizJgSupervisionInfoNew.setSequenceNbr(idxBizJgSupervisionInfoOld.getSequenceNbr());
        this.setNameByCode2SupervisionInfo(idxBizJgSupervisionInfoNew);

        String jySeq = changeJson.getString("jySeq");
        String maintenanceSeq = changeJson.getString("maintenanceSeq");
        String constructionInfoSeq = changeJson.getString("constructionInfoSeq");
        if (jySeq != null) {
            IdxBizJgInspectionDetectionInfo inspectionDetectionInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getInspectionDetectionInfoService().getById(jySeq);
            IdxBizJgInspectionDetectionInfo inspectionDetectionInfoNew = BeanUtil.copyProperties(inspectionDetectionInfoOld, IdxBizJgInspectionDetectionInfo.class);
            CommonEquipDataProcessService.castMap2Bean(changeJson, inspectionDetectionInfoNew);
            inspectionDetectionInfoNew.setSequenceNbr(inspectionDetectionInfoOld.getSequenceNbr());
            List<FieldChangeMeta> inspectionFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getInspectionDetectionInfoService().getBaseMapper(), inspectionDetectionInfoOld, inspectionDetectionInfoNew, useInfoNew.getRecord(), "SEQUENCE_NBR", inspectionDetectionInfoOld.getSequenceNbr());
            allChangeColumns.addAll(inspectionFieldChangeMetas);
            esUpdateService.updateEsData(record, inspectionDetectionInfoNew);
        }
        if (maintenanceSeq != null) {
            IdxBizJgMaintenanceRecordInfo idxBizJgMaintenanceRecordInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgMaintenanceRecordInfoService().getById(maintenanceSeq);
            IdxBizJgMaintenanceRecordInfo idxBizJgMaintenanceRecordInfoNew = BeanUtil.copyProperties(idxBizJgMaintenanceRecordInfoOld, IdxBizJgMaintenanceRecordInfo.class);
            CommonEquipDataProcessService.castMap2Bean(changeJson, idxBizJgMaintenanceRecordInfoNew);
            idxBizJgMaintenanceRecordInfoNew.setSequenceNbr(idxBizJgMaintenanceRecordInfoOld.getSequenceNbr());
            List<FieldChangeMeta> idxBizJgMaintenanceFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgMaintenanceRecordInfoService().getBaseMapper(), idxBizJgMaintenanceRecordInfoOld, idxBizJgMaintenanceRecordInfoNew, useInfoNew.getRecord(), "SEQUENCE_NBR", idxBizJgMaintenanceRecordInfoOld.getSequenceNbr());
            allChangeColumns.addAll(idxBizJgMaintenanceFieldChangeMetas);
        }
        if (constructionInfoSeq != null) {
            IdxBizJgConstructionInfo constructionInfoOld = commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgConstructionInfoService().getById(constructionInfoSeq);
            IdxBizJgConstructionInfo constructionInfoNew = BeanUtil.copyProperties(constructionInfoOld, IdxBizJgConstructionInfo.class);
            CommonEquipDataProcessService.castMap2Bean(changeJson, constructionInfoNew);
            constructionInfoNew.setSequenceNbr(constructionInfoOld.getSequenceNbr());
            commonEquipDataProcessService.setNameByCode2ConstructionInfo(constructionInfoNew);
            List<FieldChangeMeta> constructionInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgConstructionInfoService().getBaseMapper(), constructionInfoOld, constructionInfoNew, useInfoNew.getRecord(), "SEQUENCE_NBR", constructionInfoOld.getSequenceNbr());
            allChangeColumns.addAll(constructionInfoFieldChangeMetas);
        }
        // 前置校验、新数据解析
        commonEquipDataProcessService.checkValidField2(record, registerInfoNew, null, null, null);
        commonEquipDataProcessService.checkValidField2(record, factoryInfoNew, registerInfoNew.getEquList(), registerInfoNew.getEquCategory(), registerInfoNew.getEquDefine());
        commonEquipDataProcessService.checkValidField2(record, designInfoNew, registerInfoNew.getEquList(), registerInfoNew.getEquCategory(), registerInfoNew.getEquDefine());

        // 设备制造、设计、注册信息业务处理落库
        List<FieldChangeMeta> useInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getUseInfoMapper(), useInfoOld, useInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(useInfoFieldChangeMetas);

        List<FieldChangeMeta> registerInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgRegisterInfoService().getBaseMapper(), registerInfoOld, registerInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(registerInfoFieldChangeMetas);

        List<FieldChangeMeta> factoryInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgFactoryInfoMapper(), factoryInfoOld, factoryInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(factoryInfoFieldChangeMetas);

        List<FieldChangeMeta> designInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getIdxBizJgDesignInfoMapper(), designInfoOld, designInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(designInfoFieldChangeMetas);

        List<FieldChangeMeta> otherInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getIdxBizJgOtherInfoMapper(), otherInfoOld, otherInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(otherInfoFieldChangeMetas);

        List<FieldChangeMeta> idxBizJgSupervisionInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgSupervisionInfoMapper(), idxBizJgSupervisionInfoOld, idxBizJgSupervisionInfoNew, useInfoNew.getRecord(), "record", useInfoNew.getRecord());
        allChangeColumns.addAll(idxBizJgSupervisionInfoFieldChangeMetas);

        esUpdateService.updateEsData(record, registerInfoNew);
        esUpdateService.updateEsData(record, useInfoNew);
        esUpdateService.updateEsData(record, designInfoNew);
        esUpdateService.updateEsData(record, otherInfoNew);
        esUpdateService.updateEsData(record, factoryInfoNew);
        esUpdateService.updateEsData(record, idxBizJgSupervisionInfoNew);

        if("50*X".equals(idxBizJgSupervisionInfoOld.getOrgBranchCode()) && !"50*X".equals(idxBizJgSupervisionInfoNew.getOrgBranchCode())){
            Optional<ESEquipmentInfo> esEquipmentDto = esEquipmentDao.findById(record);
            if (esEquipmentDto.isPresent()) {
                ESEquipmentInfo esEquipmentInfo = esEquipmentDto.get();
                esEquipmentInfo.setORG_BRANCH_CODE(idxBizJgSupervisionInfoNew.getOrgBranchCode());
                esEquipmentInfo.setORG_BRANCH_NAME(idxBizJgSupervisionInfoNew.getOrgBranchName());
                esEquipmentDao.save(esEquipmentInfo);
            }
        }

        // 如果是气瓶则按照证更新其他同证下的气瓶字段
        this.updateOtherEquipInSameCert(useInfoNew, registerInfoNew, registerInfoOld, allChangeColumns);
        // 设备技术参数入库处理
        commonEquipDataProcessService.updateTechParamInfo(registerInfoOld.getEquList(), record, changeData, allChangeColumns);
        return HandleResult.builder().fieldChangeMetas(allChangeColumns).build();
    }

    private void updateOtherEquipInSameCert(IdxBizJgUseInfo useInfoNew, IdxBizJgRegisterInfo registerInfoNew, IdxBizJgRegisterInfo registerInfoOld, List<FieldChangeMeta> allChangeColumns) {
        // 气瓶下的相同的使用登记证编号设备更新
        String useOrgCode = registerInfoOld.getUseOrgCode();
        if (BizCommonConstant.EQU_CATEGORY_CYLINDER.equals(registerInfoNew.getEquCategory()) && StringUtils.isNotEmpty(useOrgCode)) {
            // 查询相同的使用登记证编号的设备不包含源设备
            List<IdxBizJgRegisterInfo> equipInOneCerts = commonEquipDataProcessService.getJgUseRegistrationService()
                    .getIdxBizJgRegisterInfoService()
                    .list(new LambdaQueryWrapper<IdxBizJgRegisterInfo>()
                            .eq(IdxBizJgRegisterInfo::getUseOrgCode, useOrgCode)
                            .ne(IdxBizJgRegisterInfo::getRecord, registerInfoOld.getRecord())
                            .select(TzsBaseEntity::getSequenceNbr, IdxBizJgRegisterInfo::getRecord));
            equipInOneCerts.forEach(equip -> {
                String record = equip.getRecord();
                // 使用信息
                IdxBizJgUseInfo useInfoOtherOld = commonEquipDataProcessService.getJgUseRegistrationService().getUseInfoMapper().selectOne(new LambdaQueryWrapper<IdxBizJgUseInfo>().eq(IdxBizJgUseInfo::getRecord, record));
                IdxBizJgUseInfo useInfoOtherNew = BeanUtil.copyProperties(useInfoOtherOld, IdxBizJgUseInfo.class);
                useInfoOtherNew.setProvince(useInfoNew.getProvince());
                useInfoOtherNew.setProvinceName(useInfoNew.getProvinceName());
                useInfoOtherNew.setCity(useInfoNew.getCity());
                useInfoOtherNew.setCityName(useInfoNew.getCityName());
                useInfoOtherNew.setCounty(useInfoNew.getCounty());
                useInfoOtherNew.setCountyName(useInfoNew.getCountyName());
                useInfoOtherNew.setFactoryUseSiteStreet(useInfoNew.getFactoryUseSiteStreet());
                useInfoOtherNew.setStreetName(useInfoNew.getStreetName());
                useInfoOtherNew.setAddress(useInfoNew.getAddress());
                useInfoOtherNew.setSafetyManager(useInfoNew.getSafetyManager());
                useInfoOtherNew.setPhone(useInfoNew.getPhone());
                useInfoOtherNew.setIsNotXiXian(useInfoNew.getIsNotXiXian());
                useInfoOtherNew.setEstateUnitCreditCode(useInfoNew.getEstateUnitCreditCode());
                useInfoOtherNew.setEstateUnitName(useInfoNew.getEstateUnitName());
                useInfoOtherNew.setUseDate(useInfoNew.getUseDate());
                useInfoOtherNew.setUsePlace(useInfoNew.getUsePlace());
                useInfoOtherNew.setLongitudeLatitude(useInfoNew.getLongitudeLatitude());

                // 注册信息
                IdxBizJgRegisterInfo registerInfoOtherOld = commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgRegisterInfoService().getOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, record));
                IdxBizJgRegisterInfo registerInfoOtherNew = BeanUtil.copyProperties(registerInfoOtherOld, IdxBizJgRegisterInfo.class);
                registerInfoOtherNew.setUseOrgCode(registerInfoNew.getUseOrgCode());
                registerInfoOtherNew.setCarNumber(registerInfoNew.getCarNumber());

                List<FieldChangeMeta> useInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getUseInfoMapper(), useInfoOtherOld, useInfoOtherNew, record, "record", record);
                allChangeColumns.addAll(useInfoFieldChangeMetas);

                List<FieldChangeMeta> registerInfoFieldChangeMetas = commonEquipDataProcessService.simpleTrackAndUpdate(commonEquipDataProcessService.getJgUseRegistrationService().getIdxBizJgRegisterInfoService().getBaseMapper(), registerInfoOtherOld, registerInfoOtherNew, record, "record", record);
                allChangeColumns.addAll(registerInfoFieldChangeMetas);
            });
        }
    }

    private void setNameByCode2SupervisionInfo(IdxBizJgSupervisionInfo idxBizJgSupervisionInfo) {
        String orgCode = idxBizJgSupervisionInfo.getOrgBranchCode();
        // 按照org_code查询
        if (StringUtils.isNotEmpty(orgCode)) {
            // 特殊处理orgCode
            orgCode = changeOrgBranchCode(idxBizJgSupervisionInfo.getRecord(), orgCode);
            if (!"50*X".equals(orgCode)) {
                CompanyBo companyBo = commonEquipDataProcessService.getCommonMapper().queryCompanyByOrgCode(orgCode);
                idxBizJgSupervisionInfo.setOrgBranchCode(companyBo.getOrgCode());
                idxBizJgSupervisionInfo.setOrgBranchName(companyBo.getCompanyName());
                idxBizJgSupervisionInfo.setCompanyOrgBranchCode(companyBo.getCompanyCode());
            } else {
                log.info(String.format("设备编辑未从es中查询到正确的orgCode，record为：%s", idxBizJgSupervisionInfo.getRecord()));
            }
        }
    }

    private String changeOrgBranchCode(String record, String orgCode) {
        if (!"50*X".equals(orgCode)) {
            return orgCode;
        } else {
            // 查询es
            SearchRequest request = new SearchRequest();
            request.indices("idx_biz_view_jg_all");
            SearchSourceBuilder builder = new SearchSourceBuilder();
            builder.trackTotalHits(true);
            BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
            boolMust.must(QueryBuilders.termsQuery("SEQUENCE_NBR.keyword", record));
            builder.query(boolMust);
            request.source(builder);
            try {
                SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
                if (response.getHits().getHits().length != 0) {
                    for (SearchHit hit : response.getHits().getHits()) {
                        JSONObject jsonObject = ((JSONObject) JSONObject.toJSON(hit)).getJSONObject("sourceAsMap");
                        return jsonObject.getString("ORG_BRANCH_CODE");
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return orgCode;
    }

    private void beforeCheckForUseOrgCode(IdxBizJgUseInfo useInfoOld, IdxBizJgRegisterInfo registerInfoNew) {
        // 1.使用登记证编辑时重复性校验
        if (!CylinderTypeEnum.CYLINDER.getCode().equals(registerInfoNew.getEquCategory())) {  // 非气瓶逻辑,所有设备不能重复
            if (useInfoOld.getDataSource().equals("jg_his") && StringUtils.isNotEmpty(registerInfoNew.getUseOrgCode())) {
                Boolean isUsed = commonEquipDataProcessService.getCommonService().useRegistrationCertificateAccountUnique(registerInfoNew.getUseOrgCode(), useInfoOld.getRecord());
                if (isUsed) {
                    throw new BadRequest("使用登记证编号已存在！");
                }
            }
        } else {                                                                            // 气瓶逻辑，使用单位下不能重复
            if (StringUtils.isNotEmpty(useInfoOld.getUseUnitCreditCode()) && StringUtils.isNotEmpty(registerInfoNew.getUseOrgCode())) {
                // 需求 35094 历史设备（有使用登记证）需按证录入。录入时先录入使用登记证编号。
                // 需验证录入的使用登记证编号平台是否跟当前用户（使用单位类型）一致，如跟当前用户不一致，系统给出提示“该使用登记证编号”已被“单位名称“使用”，请确认后再录入”。
                // 历史设备不限制使用登记证编号在一个单位重复录入，但需验证使用登记证编号+单位内编号唯一。（下面方法checkFactoryNumUniqueWithGasCylinder中已经校验）
                List<String> occupiedUseUnitNames = commonEquipDataProcessService.getCommonService().isRegistrationNumberUsedByOtherUnits(registerInfoNew.getUseOrgCode(), useInfoOld.getUseUnitCreditCode());
                if (!occupiedUseUnitNames.isEmpty()) {
                    throw new BadRequest("该使用登记证编号已被【" + String.join(",", occupiedUseUnitNames) + "】使用，请确认后再录入！");
                }
            }
        }
        if (!ValidationUtil.isEmpty(registerInfoNew.getUseOrgCode())){
            idxBizJgRegisterInfoServiceImpl.checkUseRegistrationCode(registerInfoNew.getUseOrgCode(), "unit");
        }
    }

    @Override
    public IBizDataChangeHandleStrategy.ModelType canHandleMode() {
        return DefaultBizDataChangeHandler.ModelType.singleEquip;
    }

    private void beforeCheckForEquCode(IdxBizJgFactoryInfo factoryInfoOld, IdxBizJgRegisterInfo registerInfoNew) {
        // 如果是用户输入的设备代码，则校验设备代码唯一性
        if (EquCodeTypeEnum.INPUT.getCode().equals(registerInfoNew.getEquCodeType())) {
            LinkedHashMap<String, String> params = Maps.newLinkedHashMap();
            params.put("EQU_CODE", registerInfoNew.getEquCode());
            params.put("SEQUENCE_NBR", registerInfoNew.getSequenceNbr());
            commonEquipDataProcessService.getJgRegisterInfoService().checkEquCodeUniqueness(params);
        }
        // 如果生成设备代码类型是系统生成并且没有值，则系统重新生成设备代码
        if (EquCodeTypeEnum.SYSTEM_GENERATED.getCode().equals(registerInfoNew.getEquCodeType()) && registerInfoNew.getEquCode() == null) {
            String receiveCompanyCode = registerInfoNew.getOrganizationCode();
            JSONObject companyTypeObj = commonEquipDataProcessService.getJgRegisterInfoService().getCompanyType();
            if (companyTypeObj != null && !"company".equals(companyTypeObj.getString("level"))) {
                // 编辑账号为接收机构人员时，receiveCompanyCode取到地市级的接收机构代码
                receiveCompanyCode = commonEquipDataProcessService.getJgUseRegistrationService().getCodeUtil().getCityRegionCode(companyTypeObj.getString("companyCode"));
            }
            if (companyTypeObj != null && "company".equals(companyTypeObj.getString("level"))) {
                // 编辑账号企业人员时，receiveCompanyCode最近一次使用登记或者安装告知或者车用气瓶登记单据的接收机构代码
                List<Map<String, String>> recentlyReceiveCompanyCode = commonEquipDataProcessService.getCommonMapper().queryRecentlyReceiveCompanyCode(registerInfoNew.getRecord());
                if (!recentlyReceiveCompanyCode.isEmpty()) {
                    // 按passedDate倒叙排序后取最新的一个
                    recentlyReceiveCompanyCode = recentlyReceiveCompanyCode.stream().filter(map -> !ValidationUtil.isEmpty(map)).collect(Collectors.toList());
                    recentlyReceiveCompanyCode.sort(Comparator.comparing(map -> map.get("passedDate")));
                    receiveCompanyCode = commonEquipDataProcessService.getJgUseRegistrationService().getCodeUtil().getCityRegionCode(recentlyReceiveCompanyCode.get(0).get("receiveCompanyCode"));
                }
            }
            String equCode = commonEquipDataProcessService.getJgRegisterInfoService().getEquCode(registerInfoNew, factoryInfoOld, receiveCompanyCode);
            registerInfoNew.setEquCode(equCode);
        }
    }
}
