package com.red.circle.other.app.command;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.other.app.dto.clientobject.SpinsTaskCO;
import com.red.circle.other.infra.database.rds.entity.task.SpinsTaskConfig;
import com.red.circle.other.infra.database.rds.entity.task.SpinsUserTaskProgress;
import com.red.circle.other.infra.database.rds.dao.task.SpinsTaskConfigDAO;
import com.red.circle.other.infra.database.rds.dao.task.SpinsUserTaskProgressDAO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 查询用户任务列表执行器
 *
 * @author system
 * @date 2025-01-21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SpinsTaskQueryExe {

    private final SpinsTaskConfigDAO spinsTaskConfigDAO;
    private final SpinsUserTaskProgressDAO spinsUserTaskProgressDAO;

    /**
     * 执行查询用户任务列表
     *
     * @param userId 用户ID
     * @return 任务列表
     */
    public List<SpinsTaskCO> execute(Long userId, Long activityId) {
        // 1. 查询所有启用的任务配置
        List<SpinsTaskConfig> taskConfigs = spinsTaskConfigDAO.selectList(
                new LambdaQueryWrapper<SpinsTaskConfig>()
                        .eq(SpinsTaskConfig::getStatus, 1)
                        .eq(SpinsTaskConfig::getLotteryActivityId, activityId)
                        .orderByAsc(SpinsTaskConfig::getSortOrder)
        );

        if (CollectionUtils.isEmpty(taskConfigs)) {
            log.warn("未查询到启用的任务配置");
            return new ArrayList<>();
        }

        // 2. 获取当前周期key
        String cycleKey = getCurrentCycleKey();

        // 3. 查询用户任务进度
        List<String> taskCodes = taskConfigs.stream()
                .map(SpinsTaskConfig::getTaskCode)
                .collect(Collectors.toList());

        List<SpinsUserTaskProgress> progressList = spinsUserTaskProgressDAO.selectList(
                new LambdaQueryWrapper<SpinsUserTaskProgress>()
                        .eq(SpinsUserTaskProgress::getUserId, userId)
                        .in(SpinsUserTaskProgress::getTaskCode, taskCodes)
                        .eq(SpinsUserTaskProgress::getCycleKey, cycleKey)
        );

        Map<String, SpinsUserTaskProgress> progressMap = progressList.stream()
                .collect(Collectors.toMap(SpinsUserTaskProgress::getTaskCode, p -> p, (p1, p2) -> p1));

        // 4. 组装返回数据
        List<SpinsTaskCO> result = new ArrayList<>();
        for (SpinsTaskConfig config : taskConfigs) {
            SpinsTaskCO taskCO = buildTaskCO(config, progressMap.get(config.getTaskCode()));
            result.add(taskCO);
        }

        return result;
    }

    /**
     * 构建任务CO对象
     */
    private SpinsTaskCO buildTaskCO(SpinsTaskConfig config, SpinsUserTaskProgress progress) {
        SpinsTaskCO taskCO = new SpinsTaskCO();
        taskCO.setTaskId(config.getId());
        taskCO.setTaskCode(config.getTaskCode());
        taskCO.setTaskName(config.getTaskName());
        taskCO.setTaskType(config.getTaskType());
        taskCO.setTaskDesc(config.getTaskDesc());
        taskCO.setIconUrl(config.getIconUrl());
        taskCO.setTargetType(config.getTargetType());
        taskCO.setTargetValue(config.getTargetValue());
        taskCO.setTargetUnit(config.getTargetUnit());
        taskCO.setRewardType(config.getRewardType());
        taskCO.setRewardValue(config.getRewardValue());

        if (progress != null) {
            taskCO.setCurrentValue(Math.min(progress.getCurrentValue(), config.getTargetValue()));
            taskCO.setTaskStatus(progress.getTaskStatus());
            taskCO.setProgressRate(progress.getProgressRate());
            taskCO.setCompleteTime(progress.getCompleteTime());
        } else {
            // 未开始的任务
            taskCO.setCurrentValue(0);
            taskCO.setTaskStatus(0);
            taskCO.setProgressRate(BigDecimal.ZERO);
        }

        return taskCO;
    }

    /**
     * 获取当前周期key（每日任务格式：yyyyMMdd）
     */
    private String getCurrentCycleKey() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }
}
