package net.northking.cctp.dw.bus;

import com.alibaba.fastjson.JSON;
import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.util.UUIDUtil;
import net.northking.cctp.dw.api.service.BugChartService;
import net.northking.cctp.dw.api.service.MtCaseDesignApiService;
import net.northking.cctp.dw.api.service.MtManualExecJobApiService;
import net.northking.cctp.dw.api.service.MtTestPointApiService;
import net.northking.cctp.dw.constant.DWError;
import net.northking.cctp.dw.constant.MQConstant;
import net.northking.cctp.dw.db.entity.*;
import net.northking.cctp.dw.db.service.*;
import net.northking.cctp.dw.dto.CltDictItem;
import net.northking.cctp.dw.dto.MtCaseDesignInfoDw;
import net.northking.cctp.dw.dto.MtTestPointSynDto;
import net.northking.cctp.dw.dto.SyncCltDictItemDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: puchao.ma
 * @date: 2021/12/14 15:31
 */
//@Component
public class RabbitMqListener {
    private final static Logger logger = LoggerFactory.getLogger(RabbitMqListener.class);
    @Autowired
    private MtTestPointApiService mtTestPointApiService;

    @Autowired
    private EntityNameCache entityNameCache;

    @Autowired
    private MtCaseDesignApiService mtCaseDesignApiService;

    @Autowired
    private MtManualExecJobApiService mtManualExecJobApiService;

    @Autowired
    private MtTestPointStatisticsService mtTestPointStatisticsService;

    @Autowired
    private MtCaseDesignChartService mtCaseDesignChartService;

    @Autowired
    private MtCaseExecChartService mtCaseExecChartService;

    @Autowired
    private BugGradeStatisticsService bugGradeStatisticsService;

    @Autowired
    private BugStatusStatisticsService bugStatusStatisticsService;

    @Autowired
    private BugTendencyChartTmpService bugTendencyChartTmpService;

    @Autowired
    private MtCaseExecTrendChartService mtCaseExecTrendChartService;

    @Autowired
    private MtLeafDesignService mtLeafDesignService;

    @Autowired
    private BugChartService bugChartService;

    @Autowired
    private BugLifeCycleChartService bugLifeCycleChartService;

    @Autowired
    private BugOverallTendencyChartService bugOverallTendencyChartService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private MidProjectInfoService midProjectInfoService;

    @Autowired
    private BugTemplateStatusService bugTemplateStatusService;

    @Autowired
    private DwCaseDesignInfoService dwCaseDesignInfoService;

    @Autowired
    private SynBugInfoService synBugInfoService;

    @Autowired
    private DwTestPointService dwTestPointService;

    @Autowired
    private DwManualExecDirService dwManualExecDirService;

    @Autowired
    private DwManualExecJobService dwManualExecJobService;
    //midProjectInfo、bugTemplateStatus、dwCaseDesignInfo、dwTestPoint、synBugInfo、dwManualExecDir、DwManualExecJob
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = "platform.exchange", type = ExchangeTypes.TOPIC),
                    value = @Queue(name = "sync.clt.dict.item.list.info.queue"),
                    key = "sync.clt.dict.item.list.info"
            )
    )
    public void syncCltDictItemList(SyncCltDictItemDto syncCltDictItemDto) {
        try {
            if (null != syncCltDictItemDto) {
                // 更新数据字典条目名称
                if (syncCltDictItemDto.getOperationType() != null && "UPDATE_DICT_ITEM".equals(syncCltDictItemDto.getOperationType())) {
                    List<String> proIdList = midProjectInfoService.findByTenantId(syncCltDictItemDto.getTenantId());
                    List<CltDictItem> cltDictItemList = syncCltDictItemDto.getCltDictItemList();
                    if (!proIdList.isEmpty() && cltDictItemList != null && !cltDictItemList.isEmpty()) {
                        CltDictItem cltDictItem = cltDictItemList.get(0);
                        Integer result = bugTemplateStatusService.updateBugStatusByCode(cltDictItem.getItemCode(), cltDictItem.getItemName(), proIdList);
                    }
                } else {
                    // 出该租户下所有的系统
                    List<String> proIdList = new ArrayList<>();
                    if (null != syncCltDictItemDto.getProjectIdList() && syncCltDictItemDto.getProjectIdList().size() != 0) {
                        proIdList.addAll(syncCltDictItemDto.getProjectIdList());
                    }
                    //删除系统对应的记录
                    if (null != proIdList && proIdList.size() != 0) {
                        bugTemplateStatusService.deleteByProIdList(proIdList);
                    }
                    //批量添加
                    List<CltDictItem> cltDictItemList = syncCltDictItemDto.getCltDictItemList();
                    List<BugTemplateStatus> bugTemplateStatusList = new ArrayList<>();
                    if (null != proIdList && proIdList.size() != 0) {
                        proIdList.forEach(proId -> {
                            cltDictItemList.forEach(cltDictItem -> {
                                BugTemplateStatus bugTemplateStatus = new BugTemplateStatus();
                                bugTemplateStatus.setProjectId(proId);
                                bugTemplateStatus.setBugStatus(cltDictItem.getItemName());
                                bugTemplateStatus.setBugStatusCode(cltDictItem.getItemCode());
                                bugTemplateStatus.setIdx(String.valueOf(cltDictItem.getIdx()));
                                bugTemplateStatus.setId(UUIDUtil.create32UUID());
                                bugTemplateStatus.setIsEndStatus(cltDictItem.getFinishedState() ? 1 : 0);
                                bugTemplateStatusList.add(bugTemplateStatus);
                            });
                        });
                        if (bugTemplateStatusList.size() != 0) {
                            bugTemplateStatusService.insertByBatch(bugTemplateStatusList);
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new PlatformRuntimeException(DWError.MQ_SYNC_CLTDICTITEM_INFO_FAILED, e);
        }
    }


    /**
     * 用例管理表全表同步
     *
     * @param mtCaseDesignInfoDwList
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = MQConstant.MQ_SYNCHRONIZATION_DATA_EXCHANGE, type = ExchangeTypes.TOPIC),
                    value = @Queue(name = MQConstant.Queue.SYNC_DESIGN_INFO_DW_QUEUE),
                    key = MQConstant.RoutingKey.SYNC_DESIGN_INFO_DW
            )
    )
    public void syncDesignInfoData(List<MtCaseDesignInfoDw> mtCaseDesignInfoDwList) {
        try {
            if (mtCaseDesignInfoDwList != null && !mtCaseDesignInfoDwList.isEmpty()) {
                // 先删除所有的数据
                List<String> deletedIds = mtCaseDesignInfoDwList.stream().map(MtCaseDesignInfoDw::getId).collect(Collectors.toList());
                dwCaseDesignInfoService.deleteBatch(deletedIds);
                // 再插入is_deleted=0的数据
                List<MtCaseDesignInfoDw> insertList = mtCaseDesignInfoDwList.stream().filter(item -> !item.getDeleted()).collect(Collectors.toList());
                if (!insertList.isEmpty()) {
                    List<DwCaseDesignInfo> dwCaseDesignInfoList = new ArrayList<>();
                    for (MtCaseDesignInfoDw item : insertList) {
                        DwCaseDesignInfo entity = new DwCaseDesignInfo();
                        BeanUtils.copyProperties(item, entity);
                        entity.setSystem(item.getUSER_DEFINED_IDX1());
                        dwCaseDesignInfoList.add(entity);
                    }
                    dwCaseDesignInfoService.insertByBatchDwCaseDesignInfo(dwCaseDesignInfoList);
                }
            }
        } catch (Exception e) {
            logger.info("============同步用例报错=====================:" + e.getMessage());
            throw new PlatformRuntimeException(DWError.MQ_SYNC_EXEC_TEND_INFO_FAILED, e);
        }
    }

    /**
     * 测试点表全表同步
     *
     * @param testPointList
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = MQConstant.MQ_SYNCHRONIZATION_DATA_EXCHANGE, type = ExchangeTypes.TOPIC),
                    value = @Queue(name = MQConstant.Queue.SYNC_POINT_INFO_ALL_QUEUE),
                    key = MQConstant.RoutingKey.SYNC_POINT_INFO_ALL
            )
    )
    public void syncTestPointData(List<MtTestPointSynDto> testPointList) {
        try {
            if (testPointList != null && !testPointList.isEmpty()) {
                // 先删除所有的数据
                List<Object> deletedIds = testPointList.stream().map(MtTestPointSynDto::getId).collect(Collectors.toList());
                dwTestPointService.deleteByPrimaryKeys(deletedIds);
                // 筛选出is_deleted=0的数据
                List<MtTestPointSynDto> insertList = testPointList.stream().filter(item -> !item.getDeleted()).collect(Collectors.toList());
                if (!insertList.isEmpty()) {
                    dwTestPointService.insertByBatchIgnore(insertList);
                }
            }
        } catch (Exception e) {
            logger.info("============同步测试点报错=====================:" + e.getMessage());
            throw new PlatformRuntimeException(DWError.MQ_SYNC_EXEC_TEND_INFO_FAILED, e);
        }
    }

    /**
     * 缺陷表全表同步
     *
     * @param dtoList
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = MQConstant.MQ_SYNCHRONIZATION_DATA_EXCHANGE, type = ExchangeTypes.TOPIC),
                    value = @Queue(name = MQConstant.Queue.SYN_BUG_INFO_QUEUE),
                    key = MQConstant.RoutingKey.SYN_BUG_INFO
            )
    )
    public void syncBugInfoData(List<SynBugInfo> dtoList) {
        try {
            if (dtoList != null && !dtoList.isEmpty()) {
                List<Object> bugIds = dtoList.stream().map(SynBugInfo::getBugId).collect(Collectors.toList());
                //先删除
                synBugInfoService.deleteByPrimaryKeys(bugIds);
                // 再批量插入
                synBugInfoService.insertBugInfoByBatch(dtoList);
            }
        } catch (Exception e) {
            logger.info("============同步缺陷报错=====================:" + e.getMessage());
            throw new PlatformRuntimeException(DWError.MQ_SYNC_EXEC_TEND_INFO_FAILED, e);
        }
    }

    /**
     * 测试执行目录表同步
     *
     * @param manualExecDirList
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = MQConstant.MQ_SYNCHRONIZATION_DATA_EXCHANGE, type = ExchangeTypes.TOPIC),
                    value = @Queue(name = MQConstant.Queue.SYNC_MANUAL_EXEC_DIR_QUEUE),
                    key = MQConstant.RoutingKey.SYNC_MANUAL_EXEC_DIR
            )
    )
    public void syncManualExecDirData(List<DwManualExecDir> manualExecDirList) {
        try {
            logger.info(JSON.toJSONString(manualExecDirList));
            if (manualExecDirList != null && !manualExecDirList.isEmpty()) {
                List<Object> dirIds = manualExecDirList.stream().map(DwManualExecDir::getId).collect(Collectors.toList());
                // 先删除
                dwManualExecDirService.deleteByPrimaryKeys(dirIds);
                // 筛选出is_deleted=0的数据
                List<DwManualExecDir> insertList = manualExecDirList.stream().filter(item -> !item.getDeleted()).collect(Collectors.toList());
                if (!insertList.isEmpty()) {
                    dwManualExecDirService.insertManualExecDirByBatch(insertList);
                }
            }
        } catch (Exception e) {
            logger.info("============同步测试执行目录报错=====================:" + JSON.toJSONString(manualExecDirList));
            throw new PlatformRuntimeException(DWError.MQ_SYNC_EXEC_TEND_INFO_FAILED, e);
        }
    }


    /**
     * 测试执行表同步
     *
     * @param manualExecDirList
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    exchange = @Exchange(name = MQConstant.MQ_SYNCHRONIZATION_DATA_EXCHANGE, type = ExchangeTypes.TOPIC),
                    value = @Queue(name = MQConstant.Queue.SYNC_MANUAL_EXEC_JOB_QUEUE),
                    key = MQConstant.RoutingKey.SYNC_MANUAL_EXEC_JOB
            )
    )
    public void syncManualExecJobData(List<DwManualExecJob> manualExecDirList) {
        try {
            if (manualExecDirList != null && !manualExecDirList.isEmpty()) {
                List<Object> dirIds = manualExecDirList.stream().map(DwManualExecJob::getId).collect(Collectors.toList());
                // 先删除
                dwManualExecJobService.deleteByPrimaryKeys(dirIds);
                // 筛选出is_deleted=0的数据
                List<DwManualExecJob> insertList = manualExecDirList.stream().filter(item -> !item.getDeleted()).collect(Collectors.toList());
                if (!insertList.isEmpty()) {
                    dwManualExecJobService.insertManualExecJobByBatch(insertList);
                }
            }
        } catch (Exception e) {
            logger.info("============同步测试执行目录报错=====================:" + e.getMessage());
            throw new PlatformRuntimeException(DWError.MQ_SYNC_EXEC_TEND_INFO_FAILED, e);
        }
    }
}
