package com.zcloud.safetyDutyList.command.tasklist;

import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.safetyDutyList.domain.enums.SwitchFlagEnum;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskDetailGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskExecutionGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListGateway;
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.TaskListE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListIssueE;
import com.zcloud.safetyDutyList.dto.tasklist.TaskListIssueCmd;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 清单下发执行器
 * <p>
 * 处理安全责任清单下发的业务逻辑：
 *   1. 校验清单是否存在且开关为开启状态
 *   2. 创建清单下发记录（TaskListIssueE）
 *   3. 根据清单下的任务模板，为每个任务创建任务执行记录（TaskExecutionE）
 */
@Component
@AllArgsConstructor
public class TaskListIssueExe {
    private final TaskListGateway taskListGateway;
    private final TaskListIssueGateway taskListIssueGateway;
    private final TaskDetailGateway taskDetailGateway;
    private final TaskExecutionGateway taskExecutionGateway;

    @Transactional(rollbackFor = Exception.class)
    public void execute(TaskListIssueCmd cmd) {

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

        // 处理周期时间
        LocalDateTime startTime = cmd.getPeriodStartTime().atDay(1).atStartOfDay();
        LocalDateTime endTime = cmd.getPeriodEndTime().atEndOfMonth().atTime(23, 59, 59);

        // 重复下发校验（同一清单+公司+部门+人员+时间段重叠）
        if (isDuplicateIssue(cmd.getTaskListId(), cmd.getExecuteCorpId(), cmd.getExecuteDepartmentId(), cmd.getExecuteUserId(), startTime, endTime)) {
            throw new BizException("该清单在相同时间段内已下发给该公司部门人员，不可重复下发");
        }

        TaskListE taskListE = taskListGateway.getInfoByTaskListId(cmd.getTaskListId());
        if (taskListE == null) {
            throw new BizException("任务清单不存在");
        }
        if (!SwitchFlagEnum.ON.getCode().equals(taskListE.getSwitchFlag())) {
            throw new BizException("仅可下发开启状态的任务清单");
        }

        List<TaskDetailE> taskDetailList = taskDetailGateway.listByTaskListId(taskListE.getTaskListId());
        if (taskDetailList == null || taskDetailList.isEmpty()) {
            throw new BizException("任务清单下无任务可执行");
        }

        // 2. 创建清单下发记录
        TaskListIssueE issueE = new TaskListIssueE();
        issueE.init();
        issueE.setTaskListId(cmd.getTaskListId());
        issueE.setExecuteCorpId(cmd.getExecuteCorpId());
        issueE.setExecuteDepartmentId(cmd.getExecuteDepartmentId());
        issueE.setExecuteUserId(cmd.getExecuteUserId());
        issueE.setIssueStatus(1);
        issueE.setIssueTime(LocalDateTime.now());
        issueE.setIssueCorpId(ssoUser.getTenantId());
        issueE.setIssueDepartmentId(ssoUser.getOrgId());
        issueE.setIssueUserId(ssoUser.getUserId());
        issueE.setPeriodStartTime(startTime);
        issueE.setPeriodEndTime(endTime);
        issueE.setStatus(TaskStatusEnum.IN_PROGRESS.getCode());
        boolean issueRes = taskListIssueGateway.add(issueE);
        if (!issueRes) {
            throw new BizException("下发失败");
        }

        // 3. 查询清单下所有任务模板，创建任务执行记录
        List<TaskDetailE> detailList = taskDetailGateway.listByTaskListId(cmd.getTaskListId());
        if (detailList != null && !detailList.isEmpty()) {
            List<TaskExecutionE> executionList = new ArrayList<>();
            for (TaskDetailE detailE : detailList) {
                TaskExecutionE executionE = new TaskExecutionE();
                executionE.init();
                executionE.setTaskIssueId(issueE.getTaskIssueId());
                executionE.setTaskDetailId(detailE.getTaskDetailId());
                executionE.setTaskListId(cmd.getTaskListId());
                executionE.setTaskStatus(TaskStatusEnum.IN_PROGRESS.getCode());
                executionE.setFeedbackStatus(1);
                executionList.add(executionE);
            }
            taskExecutionGateway.batchAdd(executionList);
        }
    }

    /**
     * 判断当前清单是否重复下发（同一清单+公司+部门+人员+时间段重叠）
     */
    private Boolean isDuplicateIssue(String taskListId, Long executeCorpId, Long executeDepartmentId, Long executeUserId,
                                      LocalDateTime periodStartTime, LocalDateTime periodEndTime) {
        return taskListIssueGateway.isDuplicateIssue(taskListId, executeCorpId, executeDepartmentId, executeUserId, periodStartTime, periodEndTime);
    }
}
