package com.njcn.rdms.module.project.service.project.permission;

import com.njcn.rdms.module.project.dal.dataobject.project.ProjectDO;
import com.njcn.rdms.module.project.dal.mysql.project.ProjectMapper;
import com.njcn.rdms.module.project.dal.mysql.project.execution.ExecutionAssigneeMapper;
import com.njcn.rdms.module.project.dal.mysql.project.execution.ProjectExecutionMapper;
import com.njcn.rdms.module.project.dal.mysql.project.task.ProjectTaskMapper;
import com.njcn.rdms.module.project.dal.mysql.project.task.TaskAssigneeMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
 * VisibilityScopeResolver 实现。
 *
 * 短路：project.manager_user_id == userId → seesAll=true，跳过任何 ID 过滤。
 * 非项目经理：并集 4 个 Mapper 来源得到可见的 executionIds / taskIds。
 *
 * 任务的"执行 owner 看执行下所有任务"短路不在此处实现，
 * 由 ProjectTaskServiceImpl / ProjectStatusBoardServiceImpl 在调用本 Resolver 前自行判定。
 * 本 Resolver 仅负责"参与者 → 可见 ID 集合"的纯查询。
 */
@Service
public class VisibilityScopeResolverImpl implements VisibilityScopeResolver {

    @Resource
    private ProjectMapper projectMapper;
    @Resource
    private ProjectExecutionMapper projectExecutionMapper;
    @Resource
    private ExecutionAssigneeMapper executionAssigneeMapper;
    @Resource
    private ProjectTaskMapper projectTaskMapper;
    @Resource
    private TaskAssigneeMapper taskAssigneeMapper;

    @Override
    public VisibilityScope resolveForProject(Long projectId, Long userId) {
        if (isProjectManager(projectId, userId)) {
            return VisibilityScope.all();
        }
        Set<Long> executionIds = new LinkedHashSet<>();
        executionIds.addAll(projectExecutionMapper.selectIdsByProjectIdAndOwnerId(projectId, userId));
        executionIds.addAll(executionAssigneeMapper.selectActiveExecutionIdsByProjectIdAndUserId(projectId, userId));

        Set<Long> taskIds = new LinkedHashSet<>();
        taskIds.addAll(projectTaskMapper.selectOwnedTaskAndDescendantIdsByProjectIdAndUserId(projectId, userId));
        taskIds.addAll(taskAssigneeMapper.selectActiveTaskIdsByProjectIdAndUserId(projectId, userId));

        return VisibilityScope.of(executionIds, taskIds);
    }

    @Override
    public VisibilityScope resolveForExecution(Long projectId, Long executionId, Long userId) {
        if (isProjectManager(projectId, userId)) {
            return VisibilityScope.all();
        }
        // executionIds 在执行维度无用，统一传空集；调用方靠 taskIds 过滤分页/计数。
        Set<Long> taskIds = new LinkedHashSet<>();
        taskIds.addAll(projectTaskMapper.selectOwnedTaskAndDescendantIdsByExecutionIdAndUserId(projectId, executionId, userId));
        taskIds.addAll(taskAssigneeMapper.selectActiveTaskIdsByProjectIdAndExecutionIdAndUserId(projectId, executionId, userId));

        return VisibilityScope.of(Set.of(), taskIds);
    }

    private boolean isProjectManager(Long projectId, Long userId) {
        if (projectId == null || userId == null) {
            return false;
        }
        ProjectDO project = projectMapper.selectById(projectId);
        return project != null && Objects.equals(project.getManagerUserId(), userId);
    }
}
