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

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.JgChangeRegistrationReform;
import com.yeejoin.amos.boot.module.jg.api.entity.JgChangeRegistrationReformEq;
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.ICommonService;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.JgChangeRegistrationReformEqServiceImpl;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.JgChangeRegistrationReformServiceImpl;
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 org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Getter
public class ChangeRegistrationReformEditUpdateService {

    private final JgChangeRegistrationReformServiceImpl mainService;

    private final JgChangeRegistrationReformEqServiceImpl eqService;

    private final ChangeRegisterReformBackupManager registerReformBackupManager;

    private final CommonEquipDataProcessService commonEquipDataProcessService;

    private final ICommonService commonServiceBiz;

    private final PieLineDataChangeServiceImpl pieLineDataChangeService;

    public Set<String> getEqsByApplyNo(String applyNo) {
        JgChangeRegistrationReform jgChangeRegistrationReform = mainService.getOne(new LambdaQueryWrapper<JgChangeRegistrationReform>().eq(JgChangeRegistrationReform::getApplyNo, applyNo).select(BaseEntity::getSequenceNbr));
        List<JgChangeRegistrationReformEq> eqs = eqService.list(new LambdaQueryWrapper<JgChangeRegistrationReformEq>().eq(JgChangeRegistrationReformEq::getEquipTransferId, jgChangeRegistrationReform.getSequenceNbr()).select(JgChangeRegistrationReformEq::getEquId, BaseEntity::getSequenceNbr));
        return eqs.stream().map(JgChangeRegistrationReformEq::getEquId).collect(Collectors.toSet());
    }

    public JgChangeRegistrationReform getOneByApplyNo(String applyNo) {
        return mainService.getOne(new LambdaQueryWrapper<JgChangeRegistrationReform>().eq(JgChangeRegistrationReform::getApplyNo, applyNo));
    }


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


    public void updateBizInfo(String bizId, List<FieldChangeMeta> allChangeColumns, String applyNo, IBizDataChangeHandleStrategy.ModelType model, Map<String, List<PipelineChangeItemDto>> pipelineChangeItemMap) {
        // 压力管道在使用登记页面进行管道增减后，更新eq表、修改管道的状态
        if (model.equals(IBizDataChangeHandleStrategy.ModelType.singleProject)) {
            JgChangeRegistrationReform jgChangeRegistrationReform = mainService.getOne(new LambdaQueryWrapper<JgChangeRegistrationReform>().select(BaseEntity::getSequenceNbr, JgChangeRegistrationReform::getAuditStatus, JgChangeRegistrationReform::getProjectContraptionId, JgChangeRegistrationReform::getUseRegistrationCode).eq(JgChangeRegistrationReform::getApplyNo, applyNo));
            if (!jgChangeRegistrationReform.getAuditStatus().equals(FlowStatusEnum.TO_BE_FINISHED.getName())) { // 非完成状态更新eq表
                // 1.eq表删除
                this.deleteRelationEq(jgChangeRegistrationReform.getSequenceNbr());
                // 2.插入eq表
                List<JgChangeRegistrationReformEq> registrationEqs = this.buildPipelineEqs(pipelineChangeItemMap);
                this.insertRelationEq(jgChangeRegistrationReform.getSequenceNbr(), registrationEqs);
                // 3.json history插入
                IdxBizJgProjectContraption projectContraption = commonEquipDataProcessService.getIdxBizJgProjectContraptionServiceImpl().getById(jgChangeRegistrationReform.getProjectContraptionId());
                JSONObject jsonObject = mainService.getHisData(applyNo);
                jsonObject.remove("equipmentLists");
                jsonObject.put("pipelineLength", pieLineDataChangeService.calPipelineLength(pipelineChangeItemMap));
                jsonObject.put("projectContraptionNo", projectContraption.getProjectContraptionNo());
                jsonObject.put("projectContraption", projectContraption.getProjectContraption());
                jsonObject.put("equipmentLists", pieLineDataChangeService.buildEquipmentLists(pipelineChangeItemMap));
                commonServiceBiz.saveOrUpdateHistory("", jsonObject, bizId, applyNo);
                // 4.管道名称修改
                LambdaUpdateWrapper<JgChangeRegistrationReform> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(JgChangeRegistrationReform::getSequenceNbr, jgChangeRegistrationReform.getSequenceNbr());
                updateWrapper.set(JgChangeRegistrationReform::getProjectContraption, projectContraption.getProjectContraption());
                mainService.update(updateWrapper);
            } else {                                                                                      // 完成时，把管道更新为已纳管状态
                // 按照装置id查询装置下管道，更新为已纳管状态
                List<IdxBizJgUseInfo> useInfos = commonEquipDataProcessService.getIdxBizJgUseInfoService().list(new LambdaQueryWrapper<IdxBizJgUseInfo>().eq(IdxBizJgUseInfo::getProjectContraptionId, jgChangeRegistrationReform.getProjectContraptionId()).eq(IdxBizJgUseInfo::getIsIntoManagement, false).select(TzsBaseEntity::getSequenceNbr, IdxBizJgUseInfo::getRecord));
                useInfos.parallelStream().forEach(e -> {
                    commonEquipDataProcessService.setNewPipeline2IntoManage(e);
                    commonEquipDataProcessService.updateUseOrgCode2NewPipeline(e, jgChangeRegistrationReform.getUseRegistrationCode());
                });
            }
            // 记录本次维护管道的日志
            this.updatePipelineData(allChangeColumns, applyNo, model);
        }
    }


    private List<JgChangeRegistrationReformEq> 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 -> {
            JgChangeRegistrationReformEq useRegistrationEq = new JgChangeRegistrationReformEq();
            useRegistrationEq.setEquId(item.getRecord());
            return useRegistrationEq;
        }).collect(Collectors.toList());
    }


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

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

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


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