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

import com.red.circle.other.domain.admintask.AdminTaskRecord;
import com.red.circle.other.domain.admintask.AdminTaskType;
import com.red.circle.other.domain.gateway.AdminTaskGateway;
import com.red.circle.other.app.dto.cmd.AdminTaskProgressUpdateCmd;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

/**
 * 管理员任务进度更新执行器
 *
 * @author tf
 * @date 2025-11-25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AdminTaskProgressUpdateCmdExe {

    private final AdminTaskGateway adminTaskGateway;

    private static final int HOURS_PER_WORKING_DAY = 2;

    public AdminTaskRecord execute(AdminTaskProgressUpdateCmd cmd) {
        LocalDate cycleStartDate = cmd.getCycleStartDate() != null ? cmd.getCycleStartDate() : getCurrentCycleStartDate();

        // 校验任务类型
        AdminTaskType taskType = AdminTaskType.fromCode(cmd.getTaskType());
        if (taskType == null) {
            throw new RuntimeException("无效的任务类型: " + cmd.getTaskType());
        }

        // 增量更新任务进度
        AdminTaskRecord updatedRecord = adminTaskGateway.incrementCompletedCount(
                cmd.getUserId(),
                cmd.getTaskType(),
                cycleStartDate,
                cmd.getIncrementValue()
        );

        if (updatedRecord == null) {
            throw new RuntimeException("任务记录不存在");
        }

        // 检查是否达到目标，更新状态
        if (updatedRecord.reachedTarget() && !updatedRecord.isCompleted()) {
            adminTaskGateway.markAsCompleted(cmd.getUserId(), cmd.getTaskType(), cycleStartDate);
            updatedRecord.setStatus("COMPLETED");
        }

        // 特殊处理：麦克风使用时长影响工作天数
        if (AdminTaskType.MIC_USAGE.getCode().equals(cmd.getTaskType())) {
            int workingDays = updatedRecord.getCompletedCount() / HOURS_PER_WORKING_DAY;
            AdminTaskRecord workingDaysRecord = adminTaskGateway.updateCompletedCountAbsolute(
                    cmd.getUserId(),
                    AdminTaskType.WORKING_DAYS.getCode(),
                    cycleStartDate,
                    workingDays
            );

            // 检查工作天数是否达到目标
            if (workingDaysRecord != null && workingDaysRecord.reachedTarget() && !workingDaysRecord.isCompleted()) {
                adminTaskGateway.markAsCompleted(cmd.getUserId(), AdminTaskType.WORKING_DAYS.getCode(), cycleStartDate);
            }
        }

        return updatedRecord;
    }

    /**
     * 获取当前周期开始日期
     */
    private LocalDate getCurrentCycleStartDate() {
        LocalDate now = LocalDate.now();
        int dayOfMonth = now.getDayOfMonth();

        if (dayOfMonth <= 15) {
            return LocalDate.of(now.getYear(), now.getMonth(), 1);
        } else {
            return LocalDate.of(now.getYear(), now.getMonth(), 16);
        }
    }
}
