package com.zcloud.safetyDutyList.command.tasklist;

import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskDetailGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskExecutionGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListIssueGateway;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskDetailE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskExecutionE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListIssueE;
import com.zcloud.safetyDutyList.dto.tasklist.TaskDetailUpdateScoreCmd;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
@AllArgsConstructor
public class TaskDetailUpdateScoreExe {
    private final TaskExecutionGateway taskExecutionGateway;
    private final TaskDetailGateway taskDetailGateway;
    private final TaskListIssueGateway taskListIssueGateway;

    public void execute(TaskDetailUpdateScoreCmd cmd) {

        SSOUser ssoUser = AuthContext.getCurrentUser();
        if (ssoUser == null) {
            throw new BizException("用户未登录");
        }

        // 1. 查询任务执行记录
        TaskExecutionE executionE = taskExecutionGateway.getByTaskExecutionId(cmd.getTaskExecutionId());
        if (executionE == null) {
            throw new BizException("任务执行记录不存在");
        }
        if (executionE.getTaskStatus() == 1) {
            throw new BizException("任务正在进行，不能评分");
        }

        // 2. 查询任务模板获取分值上限
        TaskDetailE detailE = taskDetailGateway.getByTaskDetailId(executionE.getTaskDetailId());
        if (detailE != null && detailE.getTaskScore() != null
                && cmd.getTaskRating().compareTo(detailE.getTaskScore()) > 0) {
            throw new BizException("评分不能超过任务分值");
        }
        if (executionE.getTaskRating() != null) {
            throw new BizException("已经评分禁止再次评分");
        }

        // 3. 更新任务执行记录评分
        executionE.setTaskRating(cmd.getTaskRating());
        executionE.setRatingTime(LocalDateTime.now());
        executionE.setRatingDepartmentId(ssoUser.getOrgId());
        executionE.setRatingUserId(ssoUser.getUserId());
        boolean res = taskExecutionGateway.update(executionE);
        if (!res) {
            throw new BizException("评分失败");
        }

        // 4. 同步更新下发记录分数
        syncIssueScore(executionE.getTaskIssueId(), ssoUser);
    }

    /**
     * 同步下发记录分数：当该下发记录下所有任务执行都已评分时，汇总更新下发记录分数
     */
    private void syncIssueScore(String taskIssueId, SSOUser ssoUser) {
        List<TaskExecutionE> allExecutions = taskExecutionGateway.listByTaskIssueId(taskIssueId);
        if (allExecutions == null || allExecutions.isEmpty()) {
            return;
        }
        boolean allScored = allExecutions.stream().allMatch(e -> e.getTaskRating() != null);
        if (!allScored) {
            log.info("【下发记录评分同步】下发记录[{}]下仍有未评分任务，暂不更新分数", taskIssueId);
            return;
        }
        BigDecimal totalRating = allExecutions.stream()
                .map(TaskExecutionE::getTaskRating)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        TaskListIssueE issueE = taskListIssueGateway.getByTaskIssueId(taskIssueId);
        if (issueE == null) {
            log.warn("【下发记录评分同步】下发记录[{}]不存在，跳过同步", taskIssueId);
            return;
        }
        issueE.setRatingScore(totalRating);
        issueE.setRatingUserId(ssoUser.getUserId());
        issueE.setRatingDepartmentId(ssoUser.getOrgId());
        boolean updateRes = taskListIssueGateway.update(issueE);
        if (updateRes) {
            log.info("【下发记录评分同步】下发记录[{}]分数已更新为{}，评分人：{}", taskIssueId, totalRating, ssoUser.getUserId());
        } else {
            log.warn("【下发记录评分同步】下发记录[{}]分数更新失败", taskIssueId);
        }
    }
}
