package jnpf.cultivate.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import jnpf.cultivate.mapper.FtbCultivateLearnTaskMapper;
import jnpf.cultivate.service.FtbCultivateLearnTaskListService;
import jnpf.cultivate.utils.CultivateLearnUtils;
import jnpf.cultivate.utils.CultivateTaskLeanAsyncDealUtil;
import jnpf.model.cultivate.dto.learn.BatchCommonCountDto;
import jnpf.model.cultivate.po.learn.FtbCultivateLearnTask;
import jnpf.model.cultivate.req.learn.QueryLearnTaskListReq;
import jnpf.model.cultivate.vo.learn.FtbCultivateLearnTaskInfoListVO;
import jnpf.model.cultivate.vo.learn.WebLearnTaskDto;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

/**
 * @Author: xuguilin
 * @create: 2024/9/9:14:50
 */
@Service
public class FtbCultivateLearnTaskListServiceImpl implements FtbCultivateLearnTaskListService {

    @Autowired
    private FtbCultivateLearnTaskMapper ftbCultivateLearnTaskMapper;


    @Autowired
    private CultivateLearnUtils cultivateLearnUtils;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CultivateTaskLeanAsyncDealUtil cultivateTaskLeanAsyncDealUtil;


    /**
     * 获取任务列表
     *
     * @param req
     * @return
     */
    @Override
    public PageInfo<FtbCultivateLearnTaskInfoListVO> getWebPageList(QueryLearnTaskListReq req) {
        if (StringUtils.isNotEmpty(req.getKeyWord())) {
            req.setKeyWord(req.getKeyWord().trim());
        }
//        preUpdateTaskStatus(cultivateLearnUtils.getTenantId());
        Page<FtbCultivateLearnTaskInfoListVO> queryPage = ftbCultivateLearnTaskMapper.getMyWebPageList(Page.of(req.getCurrentPage(), req.getPageSize()), req);
        List<FtbCultivateLearnTaskInfoListVO> records = queryPage.getRecords();
        cultivateLearnUtils.fillTaskInfoList(records);
        //构建分页返回数据
        PageInfo<FtbCultivateLearnTaskInfoListVO> pageInfo = new PageInfo<>();
        pageInfo.setList(records);
        pageInfo.setPageSize((int) queryPage.getSize());
        pageInfo.setPageNum((int) queryPage.getCurrent());
        pageInfo.setTotal((int) queryPage.getTotal());
        return pageInfo;
    }

    /**
     * web端统计所有任务数量接口
     *
     * @return
     */

    @Override
    public WebLearnTaskDto countTaskNumber() {
        
        // 使用单次聚合查询替代6次独立查询,提升性能
        QueryWrapper<FtbCultivateLearnTask> wrapper = new QueryWrapper<>();
        wrapper.select(
            "COUNT(*) as all_num",
            "SUM(CASE WHEN F_TaskType = 1 THEN 1 ELSE 0 END) as time_limit_num",
            "SUM(CASE WHEN F_TaskType = 0 THEN 1 ELSE 0 END) as long_term_num",
            "SUM(CASE WHEN F_Status = 2 THEN 1 ELSE 0 END) as running_num",
            "SUM(CASE WHEN F_Status = 3 THEN 1 ELSE 0 END) as over_num",
            "SUM(CASE WHEN F_Status = 4 THEN 1 ELSE 0 END) as stop_num"
        ).eq("F_EnableMark", 0);
        
        Map<String, Object> result = ftbCultivateLearnTaskMapper.selectMaps(wrapper).get(0);
        
        WebLearnTaskDto dto = new WebLearnTaskDto();
        dto.setAllNum(getLongValue(result.get("all_num")));
        dto.setTimeLimitNum(getLongValue(result.get("time_limit_num")));
        dto.setLongTermNum(getLongValue(result.get("long_term_num")));
        dto.setRunningNum(getLongValue(result.get("running_num")));
        dto.setOverNum(getLongValue(result.get("over_num")));
        dto.setStopNum(getLongValue(result.get("stop_num")));
        
        return dto;
    }
    
    /**
     * 安全地将Object转换为Long
     */
    private Long getLongValue(Object value) {
        if (value == null) {
            return 0L;
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        return Long.parseLong(value.toString());
    }

    /**
     * 分类统计任务数量
     *
     * @return 分类id->任务数量
     */
    @Override
    public Map<String, Integer> groupCountCateNum() {
        Map<String, Integer> ret = new HashMap<>();
        List<BatchCommonCountDto> list = ftbCultivateLearnTaskMapper.groupCountCateNum();
        if (CollectionUtil.isEmpty(list)) {
            return ret;
        }
        for (BatchCommonCountDto batchCommonCountDto : list) {
            ret.put(batchCommonCountDto.getSelectKey(), batchCommonCountDto.getNum());
        }
        return ret;
    }

    /**
     * 查询分类下是否有任务
     *
     * @param cateIds 分类IDS
     * @return true-有   false-没有
     */
    @Override
    public Boolean checkHasTask(List<String> cateIds) {
        if (CollectionUtil.isEmpty(cateIds)) {
            return false;
        }
        QueryWrapper<FtbCultivateLearnTask> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .in(FtbCultivateLearnTask::getTaskClass, cateIds)
                .eq(FtbCultivateLearnTask::getEnableMark, 0);
        Long count = ftbCultivateLearnTaskMapper.selectCount(wrapper);
        if (count == null || count <= 0) {
            return false;
        }
        return true;
    }

    /**
     * 预更新任务状态
     */
    @Override
    public void preUpdateTaskStatus(String tenantId) {
        String lockKey = "preUpdateTaskStatus:" + tenantId;
        if (redisTemplate.opsForValue().setIfAbsent(lockKey, UUID.randomUUID().toString(), 3, TimeUnit.SECONDS)) {
            try {
                Date now = new Date();
                //修改进行中
                LambdaQueryWrapper<FtbCultivateLearnTask> wrapper = new LambdaQueryWrapper<>();
                wrapper.select(FtbCultivateLearnTask::getId)
                        .le(FtbCultivateLearnTask::getTimeLimitStartTime, now)
                        .ge(FtbCultivateLearnTask::getTimeLimitEndTime, now)
                        .eq(FtbCultivateLearnTask::getStatus, 1)
                        .eq(FtbCultivateLearnTask::getTaskType, 1)
                        .eq(FtbCultivateLearnTask::getEnableMark, 0);
                List<FtbCultivateLearnTask> taskList = ftbCultivateLearnTaskMapper.selectList(wrapper);
                if (CollectionUtil.isNotEmpty(taskList)) {
                    //获取任务ids集合
                    List<String> taskIds = taskList.stream().map(FtbCultivateLearnTask::getId).collect(Collectors.toList());
                    ftbCultivateLearnTaskMapper.update(null, new LambdaUpdateWrapper<FtbCultivateLearnTask>().set(FtbCultivateLearnTask::getStatus, 2).in(FtbCultivateLearnTask::getId, taskIds).eq(FtbCultivateLearnTask::getEnableMark, 0));
                    cultivateTaskLeanAsyncDealUtil.asyncSendStartTaskLearningAlert(taskList, tenantId);
                }
                //修改结束
                ftbCultivateLearnTaskMapper.update(null, new LambdaUpdateWrapper<FtbCultivateLearnTask>().set(FtbCultivateLearnTask::getStatus, 3).le(FtbCultivateLearnTask::getTimeLimitEndTime, now).notIn(FtbCultivateLearnTask::getStatus, 0, 3, 4).eq(FtbCultivateLearnTask::getTaskType, 1).eq(FtbCultivateLearnTask::getEnableMark, 0));
                //异步处理所有用户任务的状态
                cultivateTaskLeanAsyncDealUtil.asyncUpdateUserTaskStatus(tenantId);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                redisTemplate.delete(lockKey);
            }
        }
    }
}
