package com.zanxiang.game.module.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.game.module.base.pojo.dto.SendMsgDTO;
import com.zanxiang.game.module.base.pojo.params.SendMsgTaskParam;
import com.zanxiang.game.module.base.pojo.vo.SendMsgVO;
import com.zanxiang.game.module.base.util.PageUtil;
import com.zanxiang.game.module.manage.enums.CpSendMsgTaskStatusEnum;
import com.zanxiang.game.module.manage.enums.CpSendMsgTaskTypeEnum;
import com.zanxiang.game.module.manage.enums.CpSendRoleResultEnum;
import com.zanxiang.game.module.manage.service.ICpSendMsgLogService;
import com.zanxiang.game.module.manage.service.ICpSendMsgResultService;
import com.zanxiang.game.module.manage.service.ICpSendMsgTaskService;
import com.zanxiang.game.module.mybatis.entity.CpSendMsgLog;
import com.zanxiang.game.module.mybatis.entity.CpSendMsgResult;
import com.zanxiang.game.module.mybatis.entity.CpSendMsgTask;
import com.zanxiang.game.module.mybatis.mapper.CpSendMsgTaskMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
import com.zanxiang.module.util.pojo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2024-03-14
 * @description : CP消息发送任务
 */
@Service
@Slf4j
public class CpSendMsgTaskServiceImpl extends ServiceImpl<CpSendMsgTaskMapper, CpSendMsgTask> implements ICpSendMsgTaskService {

    @Autowired
    private ICpSendMsgLogService cpSendMsgLogService;

    @Autowired
    private ICpSendMsgResultService cpSendMsgResultService;

    @Override
    public boolean reSendMsgByTaskId(Long gameId, Long taskId) {
        //查询任务
        CpSendMsgTask cpSendMsgTask = super.getById(taskId);
        if (cpSendMsgTask == null) {
            log.error("参数错误, 任务id不存在! gameId : {}, taskId : {}", gameId, taskId);
            throw new BaseException("参数错误, 任务id不存在");
        }
        //查询执行日志
        List<CpSendMsgLog> sendMsgLogList = cpSendMsgLogService.list(new LambdaQueryWrapper<CpSendMsgLog>()
                .eq(CpSendMsgLog::getGameId, gameId)
                .eq(CpSendMsgLog::getTaskId, taskId));
        if (CollectionUtils.isEmpty(sendMsgLogList)) {
            log.error("执行日志log为空! gameId : {}, taskId : {}", gameId, taskId);
            return Boolean.FALSE;
        }
        //查询日志执行结果
        sendMsgLogList.forEach(cpSendMsgLog -> {
            List<CpSendMsgResult> sendMsgResultList = cpSendMsgResultService.list(new LambdaQueryWrapper<CpSendMsgResult>()
                    .eq(CpSendMsgResult::getGameId, cpSendMsgLog.getGameId())
                    .eq(CpSendMsgResult::getTaskId, cpSendMsgLog.getTaskId())
                    .eq(CpSendMsgResult::getMsgId, cpSendMsgLog.getMsgId())
                    .eq(CpSendMsgResult::getSendStatus, CpSendRoleResultEnum.CP_SEND_ROLE_RESULT_FAIL.getValue())
            );
            if (CollectionUtils.isEmpty(sendMsgResultList)) {
                return;
            }
            cpSendMsgLogService.reCpSendMsg(cpSendMsgTask.getMsg(), cpSendMsgLog, sendMsgResultList);
        });
        return Boolean.TRUE;
    }

    @Override
    public boolean reSendMsgByResultId(Long resultId) {
        //查询执行结果
        CpSendMsgResult sendMsgResult = cpSendMsgResultService.getById(resultId);
        if (sendMsgResult == null) {
            log.error("参数错误, 执行结果id不存在! id : {}", resultId);
            throw new BaseException("参数错误, 执行结果id不存在!");
        }
        if (Objects.equals(sendMsgResult.getSendStatus(), CpSendRoleResultEnum.CP_SEND_ROLE_RESULT_SUCCESS.getValue())) {
            log.error("该发送结果已成功, 禁止重发! id : {}", resultId);
            throw new BaseException("该发送结果已成功, 禁止重发!");
        }
        //查询任务
        CpSendMsgTask cpSendMsgTask = super.getById(sendMsgResult.getTaskId());
        if (cpSendMsgTask == null) {
            log.error("参数错误, 任务id不存在! taskId : {}", sendMsgResult.getTaskId());
            throw new BaseException("参数错误, 任务id不存在");
        }
        //查询执行记录
        CpSendMsgLog cpSendMsgLog = cpSendMsgLogService.getById(sendMsgResult.getMsgId());
        if (cpSendMsgLog == null) {
            log.error("执行日志log为空! gameId : {}, taskId : {}", sendMsgResult.getGameId(), sendMsgResult.getTaskId());
            throw new BaseException("执行日志log为空!");
        }
        cpSendMsgLogService.reCpSendMsg(cpSendMsgTask.getMsg(), cpSendMsgLog, Collections.singletonList(sendMsgResult));
        return Boolean.TRUE;
    }

    @Override
    public ResultVO<Boolean> sendMsg(SendMsgDTO sendMsgDto) {
        try {
            //创建任务
            CpSendMsgTask cpSendMsgTask = createSendMsgTask(sendMsgDto);
            //保存任务
            super.save(cpSendMsgTask);
            //发消息
            cpSendMsgLogService.cpSendMsg(cpSendMsgTask.getId(), sendMsgDto.getGameId(), sendMsgDto.getMsg(), sendMsgDto.getRoles());
            //成功后修改状态
            cpSendMsgTask.setStatus(CpSendMsgTaskStatusEnum.SUCCESS_SEND.getValue());
            super.updateById(cpSendMsgTask);
            log.info("发送消息成功");
            return ResultVO.ok();
        } catch (Exception e) {
            log.error("发送消息异常, sendMsgDto : {}, e : {}", sendMsgDto, e.getMessage());
            return ResultVO.fail("发送消息异常");
        }
    }

    @Override
    public PageUtil<SendMsgVO> getSendMsgTaskList(SendMsgTaskParam param) {
        Page<CpSendMsgTask> page = super.page(new Page<>(param.getPageNum(), param.getPageSize()),
                new LambdaQueryWrapper<CpSendMsgTask>()
                        .eq(param.getGameId() != null, CpSendMsgTask::getGameId, param.getGameId())
                        .eq(StringUtils.isNotEmpty(param.getTaskStatus()), CpSendMsgTask::getStatus, param.getTaskStatus())
                        .orderByDesc(CpSendMsgTask::getCreateTime));
        List<CpSendMsgTask> cpSendMsgTasks = page.getRecords();
        List<SendMsgVO> sendMsgVos = toVo(cpSendMsgTasks);
        return new PageUtil<>(sendMsgVos, page.getTotal(), param.getPageSize(), param.getPageNum(), 0);
    }

    private List<SendMsgVO> toVo(List<CpSendMsgTask> cpSendMsgTasks) {
        if (Objects.isNull(cpSendMsgTasks) || cpSendMsgTasks.isEmpty()) {
            return null;
        }
        return cpSendMsgTasks.stream()
                .map(task -> BeanUtil.copy(task, SendMsgVO.class))
                .collect(Collectors.toList());
    }

    private CpSendMsgTask createSendMsgTask(SendMsgDTO dto) {
        CpSendMsgTask cpSendMsgTask = new CpSendMsgTask();
        cpSendMsgTask.setMsg(dto.getMsg());
        cpSendMsgTask.setRoleIdCount((long) dto.getRoles().size());
        cpSendMsgTask.setTaskName(dto.getTaskName());
        cpSendMsgTask.setTaskCondition(dto.getSendConditionJson());
        cpSendMsgTask.setGameId(dto.getGameId());
        //任务类型
        cpSendMsgTask.setType(CpSendMsgTaskTypeEnum.IMMEDIATE_TASK.getValue());
        //任务状态
        cpSendMsgTask.setStatus(CpSendMsgTaskStatusEnum.WAIT_SEND.getValue());
        cpSendMsgTask.setCreateBy(dto.getCreateBy());
        cpSendMsgTask.setCreateTime(LocalDateTime.now());
        cpSendMsgTask.setUpdateTime(LocalDateTime.now());
        return cpSendMsgTask;
    }
}
