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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
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.module.common.api.converter.CommonCustomConverter;
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.JgRegistrationHistory;
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.JgRegistrationHistoryServiceImpl;
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 org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.text.SimpleDateFormat;
import java.util.*;
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;

    private final JgRegistrationHistoryServiceImpl jgRegistrationHistoryService;

    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查询装置下管道，更新为已纳管状态
                commonEquipDataProcessService.updatePipeline2InUse(useRegistration.getProjectContraptionId(), useRegistration.getUseRegistrationCode());
            }
            // 记录本次维护管道的日志
            this.updatePipelineData(allChangeColumns, applyNo, model);
        }
    }

    /**
     * 更新使用登记单据中的登记机关及对应单据his表信息
     *
     */
    public void updateUseRegistrationInfo(String bizId, List<FieldChangeMeta> allChangeColumns) {
        Map<String, Object> useRegistrationMap = jgUseRegistrationService.getJgUseRegistrationMapper().getUseRegistrationDetail(bizId);
        if (ValidationUtil.isEmpty(useRegistrationMap)) {
            return;
        }
        JgUseRegistration jgUseRegistration = jgUseRegistrationService.getById(Objects.toString(useRegistrationMap.get("UseRegistratSequenceNbr")));
        JgRegistrationHistory jgRegistrationHistory = jgRegistrationHistoryService.getDteailByRecord(bizId, MapUtil.getStr(useRegistrationMap,"UseRegistratSequenceNbr"));
        allChangeColumns.forEach(meta -> {
            if (!ValidationUtil.isEmpty(jgUseRegistration)) {
                // 更新接收机构
                if ("receiveCompanyCode".equals(meta.getColumnKey())) {
                    String receiveCompanyCode = meta.getColumnNewValue();
                    if (receiveCompanyCode != null) {
                        jgUseRegistration.setReceiveCompanyCode(receiveCompanyCode);
                        jgUseRegistration.setReceiveOrgName(CommonCustomConverter.CompanyCodeConverter.getNameByCode(receiveCompanyCode));
                    }
                }
                // 更新首次登记日期
                if ("oRegDate".equals(meta.getColumnKey())) {
                    String regDateStr = meta.getColumnNewValue();
                    if (regDateStr != null) {
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            Date regDate = sdf.parse(regDateStr);
                            jgUseRegistration.setRegDate(regDate);
                        } catch (Exception e) {
                            // 如果日期格式不正确，则设置为null
                            jgUseRegistration.setRegDate(null);
                        }
                    }
                }
                jgUseRegistrationService.updateById(jgUseRegistration);
            }
            // 更新历史表json数据
            if (!ValidationUtil.isEmpty(jgRegistrationHistory)) {
                if ("oRegDate".equals(meta.getColumnKey())) {
                    JSONObject parsedChangeData = JSONObject.parseObject(jgRegistrationHistory.getChangeData());
                    parsedChangeData.put("oRegDate", meta.getColumnNewValue());
                    jgRegistrationHistory.setChangeData(parsedChangeData.toJSONString());
                }
                jgRegistrationHistoryService.updateById(jgRegistrationHistory);
            }
        });
    }

    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();
        }
    }
}
