package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.module.jg.api.dto.*;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistration;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistrationEq;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistrationManage;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgUseRegistrationEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgUseRegistrationManageMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IBizDataChangeHandleStrategy;
import com.yeejoin.amos.boot.module.jg.biz.service.*;
import com.yeejoin.amos.boot.module.ymt.api.entity.EquipmentCategory;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.EquipmentCategoryMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.*;

/**
 * 单个维护使用登记策略实现类
 */
@Component
public class SingleDataChangeProcessStrategy implements IChangeDataProcessStrategy {


    private final JgUseRegistrationServiceImpl useRegistrationService;

    private final JgUseRegistrationEqMapper jgRelationEquipMapper;

    private final CommonEquipDataProcessService commonEquipDataProcessService;

    private final JgUseRegistrationManageMapper registrationManageMapper;

    private final EquipmentCategoryMapper equipmentCategoryMapper;


    public SingleDataChangeProcessStrategy( JgUseRegistrationServiceImpl useRegistrationService, JgUseRegistrationEqMapper jgRelationEquipMapper, CommonEquipDataProcessService commonEquipDataProcessService, JgUseRegistrationManageMapper registrationManageMapper, EquipmentCategoryMapper equipmentCategoryMapper) {
        this.useRegistrationService = useRegistrationService;
        this.jgRelationEquipMapper = jgRelationEquipMapper;
        this.commonEquipDataProcessService = commonEquipDataProcessService;
        this.registrationManageMapper = registrationManageMapper;
        this.equipmentCategoryMapper = equipmentCategoryMapper;
    }


    @Override
    public List<ChangeDataDto> handle(Map<String, Object> changeData, String defaultChangeId) {
        String record = this.getRecord(defaultChangeId);
        List<ChangeDataDto> allChangeColumns = new ArrayList<>();
        // 新数据解析
        EquipRegisterChangeDataDto registerChangeDataDto = commonEquipDataProcessService.castMap2Bean(changeData, EquipRegisterChangeDataDto.class);
        EquipFactoryChangeDataDto factoryChangeDataDto = commonEquipDataProcessService.castMap2Bean(changeData, EquipFactoryChangeDataDto.class);
        EquipDesignChangeDataDto designChangeDataDto = commonEquipDataProcessService.castMap2Bean(changeData, EquipDesignChangeDataDto.class);
        commonEquipDataProcessService.buildChangeFields(record, designChangeDataDto, factoryChangeDataDto, registerChangeDataDto, allChangeColumns);
        // 前置校验
        commonEquipDataProcessService.checkValidField(record, registerChangeDataDto, null, null, null);
        commonEquipDataProcessService.checkValidField(record, factoryChangeDataDto, registerChangeDataDto.getEquList(), registerChangeDataDto.getEquCategory(), registerChangeDataDto.getEquDefine());
        commonEquipDataProcessService.checkValidField(record, designChangeDataDto, registerChangeDataDto.getEquList(), registerChangeDataDto.getEquCategory(), registerChangeDataDto.getEquDefine());
        // 设备制造、设计、注册信息业务处理落库
        commonEquipDataProcessService.dealBizDataForEquip(record, registerChangeDataDto);
        commonEquipDataProcessService.dealBizDataForEquip(record, factoryChangeDataDto);
        commonEquipDataProcessService.dealBizDataForEquip(record, designChangeDataDto);
        // 设备技术参数入库处理
        commonEquipDataProcessService.updateTechParamInfo(registerChangeDataDto, record, changeData, allChangeColumns);
        // 更新单据对应的证信息
        this.updateManagerCertInfo(defaultChangeId, record, registerChangeDataDto);
        return allChangeColumns;
    }

    private void updateManagerCertInfo(String applyNo, String record, EquipRegisterChangeDataDto registerChangeDataDto) {
        JgUseRegistration jgUseRegistration = useRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>()
                .eq(JgUseRegistration::getApplyNo, applyNo).select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getUseRegistrationCode));
        if (FlowStatusEnum.TO_BE_FINISHED.getName().equals(jgUseRegistration.getStatus())) {
            LambdaQueryWrapper<JgUseRegistrationManage> queryWrapper = new LambdaQueryWrapper<JgUseRegistrationManage>()
                    .eq(JgUseRegistrationManage::getUseRegistrationCode, jgUseRegistration.getUseRegistrationCode())
                    .eq(JgUseRegistrationManage::getIsDelete, 0).select(BaseEntity::getSequenceNbr,JgUseRegistrationManage::getVersion);
            JgUseRegistrationManage jgUseRegistrationManage = registrationManageMapper.selectOne(queryWrapper);
            if (jgUseRegistrationManage != null && !StringUtils.equals(jgUseRegistrationManage.getEquDefineCode(), registerChangeDataDto.getEquDefine())) {
                LambdaUpdateWrapper<JgUseRegistrationManage> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(BaseEntity::getSequenceNbr, jgUseRegistrationManage.getSequenceNbr());
                if (StringUtils.isNotEmpty(registerChangeDataDto.getEquDefine())) {
                    EquipmentCategory equipmentCategory = getEquipmentCategory(registerChangeDataDto);
                    updateWrapper.set(JgUseRegistrationManage::getEquDefineCode, registerChangeDataDto.getEquDefine());
                    updateWrapper.set(JgUseRegistrationManage::getEquDefine, equipmentCategory.getName());
                } else {
                    updateWrapper.set(JgUseRegistrationManage::getEquDefineCode, null);
                    updateWrapper.set(JgUseRegistrationManage::getEquDefine, null);
                }
                updateWrapper.set(JgUseRegistrationManage::getVersion, jgUseRegistrationManage.getVersion() + 1);
                updateWrapper.set(JgUseRegistrationManage::getRecDate, new Date());
                updateWrapper.set(JgUseRegistrationManage::getChangeReason, "设备信息变更");
                registrationManageMapper.update(null, updateWrapper);
            }
        }

    }

    private EquipmentCategory getEquipmentCategory(EquipRegisterChangeDataDto registerChangeDataDto) {
        return equipmentCategoryMapper.selectOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, registerChangeDataDto.getEquDefine()));
    }

    @Override
    public Map<String, Object> getDetail(String applyNo, String bizId) {
        if (StringUtils.isEmpty(applyNo) && StringUtils.isEmpty(bizId)) {
            throw new BadRequest("applyNo and bizId can't be empty");
        }
        if (StringUtils.isNotEmpty(applyNo)) {
            return this.getDetailByApplyNo(applyNo);
        } else {
            return this.getDetailByBizId(bizId);
        }
    }

    private Map<String, Object> getDetailByBizId(String record) {
        Map<String, Object> re = new HashMap<>();
        // 注册信息(基本信息)构建
        EquipRegisterChangeDataDto equipRegisterChangeDataDto = commonEquipDataProcessService.buildRegisterInfo(record);
        // 制造信息构建
        EquipFactoryChangeDataDto factoryChangeDataDto = commonEquipDataProcessService.buildFactoryInfo(record);
        // 设计信息构建
        EquipDesignChangeDataDto designChangeDataDto = commonEquipDataProcessService.buildDesignInfo(record);
        // 技术参数构建
        BaseTechParamsFieldDto techParamsFieldDto = commonEquipDataProcessService.buildTechParamInfo(equipRegisterChangeDataDto, record);
        re.putAll(BeanUtil.beanToMap(equipRegisterChangeDataDto));
        re.putAll(BeanUtil.beanToMap(factoryChangeDataDto));
        re.putAll(BeanUtil.beanToMap(designChangeDataDto));
        re.putAll(BeanUtil.beanToMap(techParamsFieldDto));
        commonEquipDataProcessService.castJsonFields(re);
        return commonEquipDataProcessService.cast2UnderCase(re);
    }


    public Map<String, Object> getDetailByApplyNo(String bizId) {
        String record = this.getRecord(bizId);
        return getDetailByBizId(record);
    }


    public String getRecord(String applyNo) {
        JgUseRegistration jgUseRegistration = useRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>()
                .eq(JgUseRegistration::getApplyNo, applyNo).select(BaseEntity::getSequenceNbr));
        LambdaQueryWrapper<JgUseRegistrationEq> eq = new QueryWrapper<JgUseRegistrationEq>().lambda()
                .eq(JgUseRegistrationEq::getEquipTransferId, jgUseRegistration.getSequenceNbr())
                .eq(JgUseRegistrationEq::getIsDelete, false).select(JgUseRegistrationEq::getEquId);
        JgUseRegistrationEq jgUseRegistrationEq = jgRelationEquipMapper.selectOne(eq);
        return jgUseRegistrationEq.getEquId();
    }

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

}
