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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.module.common.biz.event.CommonPublisher;
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.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.biz.edit.event.BaseBizDataChangeEvent;
import com.yeejoin.amos.boot.module.jg.biz.edit.process.biz.DefaultBizDataChangeHandler;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

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

/**
 * 使用登记编辑处理器
 */
@Slf4j
@Service
public class UseRegisterDataChangeHandler extends DefaultBizDataChangeHandler<BaseBizDataChangeEvent> {


    private final UseRegisterUpdateService useRegisterUpdateService;

    protected UseRegisterDataChangeHandler(CommonPublisher routerEventPublisher, UseRegisterUpdateService useRegisterUpdateService, ApplicationContext applicationContext) {
        super(routerEventPublisher, applicationContext);
        this.useRegisterUpdateService = useRegisterUpdateService;
    }

    @Override
    public String canHandleBizType() {
        return BusinessTypeEnum.JG_USAGE_REGISTRATION.name();
    }

    @Override
    public Boolean beforeCheck(String bizId, String applyNo, ModelType model, Map<String, Object> changeData) {
        return true;
    }

    @Override
    public Set<String> getEqs(String applyNo) {
        JgUseRegistration useRegistration = useRegisterUpdateService.getJgUseRegistrationService().getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getStatus, JgUseRegistration::getProjectContraptionId).eq(JgUseRegistration::getApplyNo, applyNo));
        List<JgUseRegistrationEq> eqs = useRegisterUpdateService.getUseRegistrationEqService().list(new LambdaQueryWrapper<JgUseRegistrationEq>().select(JgUseRegistrationEq::getEquId).eq(JgUseRegistrationEq::getEquipTransferId, useRegistration.getSequenceNbr()));
        if (useRegistration.getStatus().equals(FlowStatusEnum.TO_BE_FINISHED.getName()) && StringUtils.isNotEmpty(useRegistration.getProjectContraptionId())) {
            // todo 已完成时查询eq + 流水表记录的通过该业务增加的管道+删除的管道查缉,新增的管道不在eq表，导致管道查询数量少
            List<String> newRecords = useRegisterUpdateService.getCommonEquipDataProcessService().getNewPipelineRecordsOfOneBiz(useRegistration.getSequenceNbr() + "", useRegisterUpdateService.getUseRegisterBackupManager());
            List<String> exists = eqs.stream().map(JgUseRegistrationEq::getEquId).collect(Collectors.toList());
            return Stream.concat(newRecords.stream(), exists.stream()).collect(Collectors.toSet());
        } else {
            // todo 流水中时回同步更新eq表 索引无需取流水数据
            return eqs.stream().map(JgUseRegistrationEq::getEquId).collect(Collectors.toSet());
        }
    }

    @Override
    public void preSave(String bizId, String applyNo, ModelType model, Map<String, Object> changeData) {
        useRegisterUpdateService.backupOPipelineData(applyNo, model);
    }

    /**
     * 管道专用
     * @param applyNo 单据号
     * 判断数据是实时落库，还是先存到json
     * @return 是否需要临时存储
     */
    @Override
    public Boolean requiresTemporarySave(String applyNo) {
        return !bizIsFinished(applyNo);
    }

    /**
     * 管道专用
     * 临时存储的json 管道
     *
     * @param applyNo 申请单号
     * @return 暂存的管道列表
     */
    @Override
    public List<PipelineChangeItemDto> getsTemporaryData(String applyNo) {
        return useRegisterUpdateService.getsTemporaryData(applyNo);
    }


    /**
     * 保存
     *
     * @param applyNo               单据编号
     * @param model                 @see IBizDataChangeHandleStrategy.ModelType
     * @param changeData            前端不支持分组-目前为平铺数据结构
     * @param allChangeColumns      变化的字段集合
     * @param pipelineChangeItemMap 变化的管道
     */
    @Override
    public List<FieldChangeMeta> postSave(String bizId, String applyNo, ModelType model, Map<String, Object> changeData, List<FieldChangeMeta> allChangeColumns, Map<String, List<PipelineChangeItemDto>> pipelineChangeItemMap) {
        List<FieldChangeMeta> bizEditColumns = new ArrayList<>();
        // 流程中时-更新单据-业务冗余的字段、eq表、管道状态,记录本次新增、编辑的管道record集合
        useRegisterUpdateService.updateBizInfo(allChangeColumns, bizId, applyNo, model, pipelineChangeItemMap);
        useRegisterUpdateService.updateUseRegistrationInfo(bizId, allChangeColumns);
        return bizEditColumns;
    }


    @Override
    public Boolean bizIsFinished(String applyNo) {
        JgUseRegistration useRegistration = useRegisterUpdateService.getJgUseRegistrationService().getOne(new LambdaQueryWrapper<JgUseRegistration>().eq(JgUseRegistration::getApplyNo, applyNo));
        return useRegistration.getStatus().equals(FlowStatusEnum.TO_BE_FINISHED.getName());
    }

    @Override
    public Set<String> getProjectContraptionIds(String applyNo) {
        JgUseRegistration useRegistration = useRegisterUpdateService.getJgUseRegistrationService().getOne(new LambdaQueryWrapper<JgUseRegistration>().select(BaseEntity::getSequenceNbr, JgUseRegistration::getApplyNo, JgUseRegistration::getProjectContraptionId).eq(JgUseRegistration::getApplyNo, applyNo));
        Set<String> projectContraptionIds = new HashSet<>();
        projectContraptionIds.add(useRegistration.getProjectContraptionId());
        projectContraptionIds.remove(null);
        projectContraptionIds.remove("");
        return projectContraptionIds;
    }
}
