package com.zcloud.domain.command;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSONObject;
import com.jjb.saas.message.client.message.facede.MessageFacade;
import com.jjb.saas.message.client.message.request.MessageSendCmd;
import com.jjb.saas.message.client.message.request.MessageTargetCmd;
import com.zcloud.domain.command.convertor.ProjectTaskGroupUserCoConvertor;
import com.zcloud.domain.command.convertor.ProjectTaskInfoCoConvertor;
import com.zcloud.domain.command.convertor.ProjectTaskScoreInfoCoConvertor;
import com.zcloud.domain.domain.config.MessageConfig;
import com.zcloud.domain.domain.enums.CommonFlagEnum;
import com.zcloud.domain.domain.enums.ProjectTaskExecuteStatusEnum;
import com.zcloud.domain.domain.gateway.ProjectTaskGateway;
import com.zcloud.domain.domain.model.ProjectTaskE;
import com.zcloud.domain.dto.ProjectTaskGroupUserAddCmd;
import com.zcloud.domain.dto.ProjectTaskInfoAddCmd;
import com.zcloud.domain.dto.ProjectTaskScoreInfoAddCmd;
import com.zcloud.domain.dto.ProjectTaskUpdateCmd;
import com.zcloud.domain.persistence.dataobject.*;
import com.zcloud.domain.persistence.repository.*;
import com.zcloud.gbscommon.todolistmq.TodoListEventPusherUtil;
import com.zcloud.gbscommon.todolistmq.event.TodoListAddBatchEvent;
import com.zcloud.gbscommon.todolistmq.event.TodoListAddEvent;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.UuidUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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


/**
 * web-app
 *
 * @Author zhaokai
 * @Date 2026-01-29 11:28:41
 */
@Component
@AllArgsConstructor
@Slf4j
public class ProjectTaskUpdateExe {
    private final ProjectTaskGateway projectTaskGateway;
    private final ProjectTaskRepository projectTaskRepository;
    private final ProjectTaskGroupUserCoConvertor projectTaskGroupUserCoConvertor;
    private final ProjectTaskGroupUserRepository projectTaskGroupUserRepository;
    private final ProjectTaskInfoCoConvertor projectTaskInfoCoConvertor;
    private final ProjectTaskInfoRepository projectTaskInfoRepository;
    private final ProjectTaskScoreInfoRepository projectTaskScoreInfoRepository;
    private final ProjectTaskScoreInfoCoConvertor projectTaskScoreInfoCoConvertor;
    private final TodoListEventPusherUtil todoListEventPusherUtil;
    private final DomainGroupRepository domainGroupRepository;
    @DubboReference
    private MessageFacade messageFacade;
    private MessageConfig messageConfig;

    @Transactional(rollbackFor = Exception.class)
    public void execute(ProjectTaskUpdateCmd projectTaskUpdateCmd) {
        ProjectTaskDO projectTaskDO = projectTaskRepository.getById(projectTaskUpdateCmd.getId());
        if (projectTaskDO == null) {
            throw new BizException("数据不存在");
        }
        if(ProjectTaskExecuteStatusEnum.FINISHED.getCode().equals(projectTaskDO.getExecuteStatus())){
            throw new BizException("已结束的课题不能修改");
        }

        ProjectTaskE projectTaskE = new ProjectTaskE();
        BeanUtils.copyProperties(projectTaskUpdateCmd, projectTaskE);
        boolean res = projectTaskGateway.update(projectTaskE);
        if (!res) {
            throw new BizException("修改失败");
        }


        List<ProjectTaskInfoAddCmd> projectTaskInfoAddCmdList = projectTaskUpdateCmd.getProjectTaskInfoAddCmdList();
        List<ProjectTaskGroupUserAddCmd> projectTaskGroupUserAddCmdList = projectTaskUpdateCmd.getProjectTaskGroupUserAddCmdList();
        List<ProjectTaskScoreInfoAddCmd> projectTaskScoreInfoAddCmdList = projectTaskUpdateCmd.getProjectTaskScoreInfoAddCmdList();

        if(CollUtil.isNotEmpty(projectTaskInfoAddCmdList)){
            projectTaskInfoRepository.deleteByProjectTaskId(projectTaskDO.getProjectTaskId());

            List<ProjectTaskInfoDO> projectTaskInfoDOList =projectTaskInfoCoConvertor.converCmdsToDOs(projectTaskInfoAddCmdList);
            projectTaskInfoDOList.forEach(
                    info -> {
                        info.setProjectTaskId(projectTaskDO.getProjectTaskId());
                        info.setProjectTaskInfoId(Tools.get32UUID());
                    }
            );
            projectTaskInfoRepository.saveBatch(projectTaskInfoDOList);
        }
        if(CollUtil.isNotEmpty(projectTaskGroupUserAddCmdList)){
            projectTaskGroupUserRepository.deleteByProjectTaskId(projectTaskDO.getProjectTaskId());
            List<ProjectTaskGroupUserDO> projectTaskGroupUserDOList =projectTaskGroupUserCoConvertor.converCmdsToDOs(projectTaskGroupUserAddCmdList);
            projectTaskGroupUserDOList.forEach(
                    info -> {
                        info.setProjectTaskId(projectTaskDO.getProjectTaskId());
                        info.setExecuteCorpinfoId(projectTaskE.getExecuteCorpinfoId());
                        info.setDomainGroupId(projectTaskE.getDomainGroupId());
                        info.setProjectTaskGroupUserId(Tools.get32UUID());
                    }
            );
            projectTaskGroupUserRepository.saveBatch(projectTaskGroupUserDOList);
        }

        //新增领域组人员信息
        if(CollUtil.isNotEmpty(projectTaskScoreInfoAddCmdList)){
            projectTaskScoreInfoRepository.deleteByProjectTaskId(projectTaskDO.getProjectTaskId());
            //新增评审人员信息
            List<ProjectTaskScoreInfoDO> projectTaskScoreInfoDOList = projectTaskScoreInfoCoConvertor.converCmdsToDOs(projectTaskScoreInfoAddCmdList);
            projectTaskScoreInfoDOList.forEach(
                    info -> {
                        info.setProjectTaskId(projectTaskDO.getProjectTaskId());
                        info.setProjectTaskScoreInfoId(Tools.get32UUID());
                    }
            );
            projectTaskScoreInfoRepository.saveBatch(projectTaskScoreInfoDOList);
        }

        //修改状态
        if (CollUtil.isNotEmpty(projectTaskGroupUserAddCmdList) && CollUtil.isNotEmpty(projectTaskScoreInfoAddCmdList)) {
            // 两个列表都不为空，设置为WAIT_PERFECT状态
            //如果当前时间大于开始时间，状态是开始状态
            if (projectTaskE.getExecutedStartDate().before(new Date())) {
                projectTaskE.setExecuteStatus(ProjectTaskExecuteStatusEnum.EXECUTING.getCode());
            }else{
                projectTaskE.setExecuteStatus(ProjectTaskExecuteStatusEnum.WAIT_PERFECT.getCode());
            }
        } else if (CollUtil.isNotEmpty(projectTaskGroupUserAddCmdList) && CollUtil.isEmpty(projectTaskScoreInfoAddCmdList)) {
            // 只有group user列表不为空，等待评分设置
            projectTaskE.setExecuteStatus(ProjectTaskExecuteStatusEnum.SCORE_WAIT_SET.getCode());
        } else if (CollUtil.isEmpty(projectTaskGroupUserAddCmdList) && CollUtil.isNotEmpty(projectTaskScoreInfoAddCmdList)) {
            // 只有score info列表不为空，等待项目组设置
            projectTaskE.setExecuteStatus(ProjectTaskExecuteStatusEnum.PROJECT_GROUP_WAIT_SET.getCode());
        }

        projectTaskGateway.update(projectTaskE);



    }

    public void updatExecuteStatusJob() {
        /** 定时修改执行状态
         * 1.查找已完善待执行的，修改为执行中
         * 2. 查找执行中的，修改为已结束
         */

        List<ProjectTaskDO> projectTaskDOList =projectTaskRepository.getWaitPerfectList();
        if(CollUtil.isNotEmpty(projectTaskDOList)){
            projectTaskDOList.forEach(info->{
                info.setExecuteStatus(ProjectTaskExecuteStatusEnum.EXECUTING.getCode());
            });
            //获取id list
            List<Long> idList = projectTaskDOList.stream().map(ProjectTaskDO::getId).collect(Collectors.toList());
            projectTaskRepository.updateExecuteStatusBatchById(ProjectTaskExecuteStatusEnum.EXECUTING.getCode(),idList);
        }


        //评分状态
        List<ProjectTaskDO> projectTaskDOExecutingList =projectTaskRepository.getExecutingList();

        if(CollUtil.isNotEmpty(projectTaskDOExecutingList)){
            projectTaskDOExecutingList.forEach(info->{
                info.setExecuteStatus(ProjectTaskExecuteStatusEnum.FINISHED.getCode());
            });
            List<Long> idFinishedList = projectTaskDOExecutingList.stream().map(ProjectTaskDO::getId).collect(Collectors.toList());
            projectTaskRepository.updateExecuteStatusBatchById(ProjectTaskExecuteStatusEnum.FINISHED.getCode(),idFinishedList);

            //每一个都需要 消息提醒和待办
            for (ProjectTaskDO projectTaskDO : projectTaskDOExecutingList) {
                try{
                    DomainGroupDO infoByGroupId = domainGroupRepository.getInfoByGroupId(projectTaskDO.getDomainGroupId());

                    List<TodoListAddEvent> todoListAddEventList = new ArrayList<>();
                    List<ProjectTaskScoreInfoDO> projectTaskScoreInfoDOList = projectTaskScoreInfoRepository.getListByTaskId(projectTaskDO.getProjectTaskId());
                    for (ProjectTaskScoreInfoDO projectTaskScoreInfoDO : projectTaskScoreInfoDOList) {
                        //发送消息
                        MessageSendCmd messageSendCmd = new MessageSendCmd();
                        messageSendCmd.setBusinessId(UuidUtil.get32UUID());
                        MessageTargetCmd messageTargetCmd = new MessageTargetCmd();
                        messageTargetCmd.setUserId(projectTaskScoreInfoDO.getUserId());
                        messageSendCmd.setTargetCmd(messageTargetCmd);
                        messageSendCmd.setSourceCode(messageConfig.getScorePending());
                        messageSendCmd.setNeedTokenEnum(false);
                        Map<String, Object> sendParams = new HashMap<String, Object>();
                        sendParams.put("SpecialLaskForceName", infoByGroupId.getDomainGroupName());
                        messageSendCmd.setParams(sendParams);
                        try{
                            log.info("任务结束消息提醒发送消息参数:messageSendCmd: {}", JSONUtil.toJsonStr(messageSendCmd));
                            SingleResponse<Boolean> d = messageFacade.send(messageSendCmd);
                            log.info("任务结束消息提醒发送消息结果:d: {}", JSONUtil.toJsonStr(d));
                        }catch (Exception e) {
                            log.error("任务结束消息提醒发送消息异常:messageSendCmd: {}", JSONUtil.toJsonStr(messageSendCmd), e);
                        }
                        //待排查 待办
                        TodoListAddEvent event = new TodoListAddEvent();
                        event.setTitle("您有一条【专项领域】待处理");
                        event.setContent("待评分");
                        event.setForeignKey(projectTaskDO.getId()); // 业务表ID -申请
                        event.setForeignSubsidiaryKey(projectTaskScoreInfoDO.getId()); // 业务附表ID 没有附表时为foreignKey的值
                        event.setReceiveUser(projectTaskScoreInfoDO.getUserId());// user表ID
                        event.setPcFlag(1); // 是否PC端待办 1是 0否
                        event.setAppFlag(0); // 是否APP端待办 1是 0否
                        event.setOtherParams(new JSONObject());
                        todoListAddEventList.add(event);
                    }

                    TodoListAddBatchEvent event3 = new TodoListAddBatchEvent();
                    event3.setTodoListAddEventList(todoListAddEventList);
                    todoListEventPusherUtil.sendMessageAddBatchEvent(event3);


                }catch (Exception e){
                    log.error("发送待办消息失败",e);
                }
            }




        }


    }
}

