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

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.entity.TzsBaseEntity;
import com.yeejoin.amos.boot.module.jg.api.dto.FieldChangeMeta;
import com.yeejoin.amos.boot.module.jg.api.dto.PipelineChangeItemDto;
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.biz.edit.constant.EditConstant;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.biz.strategy.IBizDataChangeHandleStrategy;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.equip.CommonEquipDataProcessService;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.equip.PieLineDataChangeServiceImpl;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.JgUseRegistrationEqServiceImpl;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.JgUseRegistrationServiceImpl;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgProjectContraption;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgUseInfo;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Getter
@Slf4j
public class UseRegisterUpdateService {

    private final JgUseRegistrationServiceImpl jgUseRegistrationService;

    private final CommonEquipDataProcessService commonEquipDataProcessService;

    private final JgUseRegistrationEqServiceImpl useRegistrationEqService;

    private final UseRegisterBackupManager useRegisterBackupManager;

    private final PieLineDataChangeServiceImpl pieLineDataChangeService;

    public void updateBizInfo(List<FieldChangeMeta> allChangeColumns, String bizId, String applyNo, IBizDataChangeHandleStrategy.ModelType model, Map<String, List<PipelineChangeItemDto>> pipelineChangeItemMap) {
        if (model.equals(IBizDataChangeHandleStrategy.ModelType.singleEquip)) {
            JgUseRegistration useRegistration = jgUseRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus).eq(JgUseRegistration::getApplyNo, applyNo));
            // 非管道类设备且非已完成状态时，在编辑后进行内部设备代码的更新
            if (!useRegistration.getStatus().equals(FlowStatusEnum.TO_BE_FINISHED.getName())) {
                JSONObject jsonObject = jgUseRegistrationService.getHisData(useRegistration);
                IdxBizJgUseInfo bizJgUseInfo = commonEquipDataProcessService.getIdxBizJgUseInfoService().getOneData(bizId);
                String useInnerCode = bizJgUseInfo.getUseInnerCode();
                jsonObject.put("useInnerCode", useInnerCode);
                jgUseRegistrationService.updateHistory(jsonObject, bizId, useRegistration.getSequenceNbr() + "", null);
            }
        }
        // 压力管道在使用登记页面进行管道增减后，更新eq表、修改管道的状态
        if (model.equals(IBizDataChangeHandleStrategy.ModelType.singleProject)) {
            JgUseRegistration useRegistration = jgUseRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getProjectContraptionId, JgUseRegistration::getOriginProjectContraptionIds, JgUseRegistration::getUseRegistrationCode).eq(JgUseRegistration::getApplyNo, applyNo));
            if (!useRegistration.getStatus().equals(FlowStatusEnum.TO_BE_FINISHED.getName())) { // 非完成状态更新eq表
                // 1.eq表删除
                this.deleteRelationEq(useRegistration.getSequenceNbr());
                // 2.插入eq表
                List<JgUseRegistrationEq> registrationEqs = this.buildPipelineEqs(pipelineChangeItemMap);
                this.insertRelationEq(useRegistration.getSequenceNbr(), registrationEqs);
                // 3.json history插入
                IdxBizJgProjectContraption projectContraption = commonEquipDataProcessService.getIdxBizJgProjectContraptionServiceImpl().getById(useRegistration.getProjectContraptionId());
                JSONObject jsonObject = jgUseRegistrationService.getHisData(useRegistration);
                jsonObject.remove("equipmentLists");
                // 使用json的数据进行计算，因为编辑的数据此时还为入库
                jsonObject.put("pipelineLength", pieLineDataChangeService.calPipelineLength(pipelineChangeItemMap));
                jsonObject.put("projectContraptionNo", projectContraption.getProjectContraptionNo());
                jsonObject.put("equipmentLists", pieLineDataChangeService.buildEquipmentLists(pipelineChangeItemMap));
                jgUseRegistrationService.updateHistory(jsonObject, bizId, useRegistration.getSequenceNbr() + "", null);
                // 4.更新单据的冗余的装置名称
                LambdaUpdateWrapper<JgUseRegistration> wrapper = new LambdaUpdateWrapper<>();
                wrapper.eq(JgUseRegistration::getSequenceNbr, useRegistration.getSequenceNbr());
                wrapper.set(JgUseRegistration::getProjectContraption, projectContraption.getProjectContraption());
                jgUseRegistrationService.update(wrapper);
            } else {                                                                          // 完成时，把管道更新为已纳管状态
                // 按照装置id查询装置下管道，更新为已纳管状态
                List<IdxBizJgUseInfo> useInfos = jgUseRegistrationService.getIdxBizJgUseInfoService().list(new LambdaQueryWrapper<IdxBizJgUseInfo>().eq(IdxBizJgUseInfo::getProjectContraptionId, useRegistration.getProjectContraptionId()).eq(IdxBizJgUseInfo::getIsIntoManagement, false).select(TzsBaseEntity::getSequenceNbr, IdxBizJgUseInfo::getRecord));
                useInfos.parallelStream().forEach(e -> {
                    commonEquipDataProcessService.setNewPipeline2IntoManage(e);
                    commonEquipDataProcessService.updateUseOrgCode2NewPipeline(e, useRegistration.getUseRegistrationCode());
                });
            }
            // 记录本次维护管道的日志
            this.updatePipelineData(allChangeColumns, applyNo, model);
        }
    }



    private List<JgUseRegistrationEq> buildPipelineEqs(Map<String, List<PipelineChangeItemDto>> pipelineChangeItemMap) {
        List<PipelineChangeItemDto> newPipelines = pipelineChangeItemMap.get(EditConstant.NEW_PIPELINES);
        List<PipelineChangeItemDto> updPipelines = pipelineChangeItemMap.get(EditConstant.UPDATE_PIPELINES);
        return Stream.concat(newPipelines.stream(), updPipelines.stream()).map(item -> {
            JgUseRegistrationEq useRegistrationEq = new JgUseRegistrationEq();
            useRegistrationEq.setEquId(item.getRecord());
            useRegistrationEq.setOriginProjectContraptionId(item.getProjectContraptionId());
            return useRegistrationEq;
        }).collect(Collectors.toList());
    }


    /**
     * 备份原始数据
     *
     * @param applyNo 单据号
     * @param model   类型
     */
    public void backupOPipelineData(String applyNo, IBizDataChangeHandleStrategy.ModelType model) {
        if (model.equals(IBizDataChangeHandleStrategy.ModelType.singleProject)) {
            JgUseRegistration useRegistration = jgUseRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getProjectContraptionId, JgUseRegistration::getOriginProjectContraptionIds).eq(JgUseRegistration::getApplyNo, applyNo));
            // 记录json，用于作废时数据的恢复
            useRegisterBackupManager.backup(useRegistration.getSequenceNbr() + "");
        }
    }

    /**
     * 更新删除、新增的管道
     *
     * @param changeMetas 记录
     * @param applyNo     单据号
     * @param model       类型
     */
    public void updatePipelineData(List<FieldChangeMeta> changeMetas, String applyNo, IBizDataChangeHandleStrategy.ModelType model) {
        // 压力管道的使用登记，在页面进行管道增减后，更新eq表
        if (model.equals(IBizDataChangeHandleStrategy.ModelType.singleProject)) {
            JgUseRegistration useRegistration = jgUseRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getProjectContraptionId, JgUseRegistration::getOriginProjectContraptionIds).eq(JgUseRegistration::getApplyNo, applyNo));
            // 更新本次新增或者编辑的管道record
            useRegisterBackupManager.updateLastOne(useRegistration.getSequenceNbr() + "", changeMetas);
        }
    }

    private void insertRelationEq(Long sequenceNbr, List<JgUseRegistrationEq> eqs) {
        eqs.forEach(e -> {
            e.setRecDate(new Date());
            e.setRecUserId(RequestContext.getExeUserId());
            e.setEquipTransferId(sequenceNbr + "");
        });
        jgUseRegistrationService.getJgUseRegistrationEqService().saveBatch(eqs);
    }

    private void deleteRelationEq(Long sequenceNbr) {
        jgUseRegistrationService.getJgUseRegistrationEqService().remove(new LambdaQueryWrapper<JgUseRegistrationEq>().eq(JgUseRegistrationEq::getEquipTransferId, sequenceNbr));
    }


    public List<PipelineChangeItemDto> getsTemporaryData(String applyNo) {
        JgUseRegistration useRegistration = jgUseRegistrationService.getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getProjectContraptionId, JgUseRegistration::getOriginProjectContraptionIds).eq(JgUseRegistration::getApplyNo, applyNo));
        JSONObject jsonObject = jgUseRegistrationService.getHisData(useRegistration);
        if (StringUtils.isNotEmpty(useRegistration.getProjectContraptionId())) {
            List<Map<String, Object>> equipmentLists = (List<Map<String, Object>>) jsonObject.get("equipmentLists");
            return BeanUtil.copyToList(equipmentLists, PipelineChangeItemDto.class);
        } else {
            return Collections.emptyList();
        }
    }
}
