package tech.easyflow.ai.service;

import org.springframework.stereotype.Service;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.common.constant.enums.EnumDataStatus;
import tech.easyflow.common.entity.LoginAccount;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.system.enums.CategoryResourceType;
import tech.easyflow.system.enums.ResourceAction;
import tech.easyflow.system.service.ResourceAccessService;

import java.math.BigInteger;
import java.util.Objects;

/**
 * 工作流使用权限校验服务。
 *
 * <p>统一封装工作流存在性、租户、启用状态和资源使用权限校验，供页面能力和后台任务复用。</p>
 */
@Service
public class WorkflowUsageAuthorizationService {

    /** 工作流服务。 */
    private final WorkflowService workflowService;

    /** 资源访问控制服务。 */
    private final ResourceAccessService resourceAccessService;

    /**
     * 创建工作流使用权限校验服务。
     *
     * @param workflowService 工作流服务
     * @param resourceAccessService 资源访问控制服务
     */
    public WorkflowUsageAuthorizationService(
            WorkflowService workflowService,
            ResourceAccessService resourceAccessService) {
        this.workflowService = workflowService;
        this.resourceAccessService = resourceAccessService;
    }

    /**
     * 获取当前账号可使用的启用工作流。
     *
     * @param workflowId 工作流 ID
     * @param account 使用工作流的账号
     * @param denyMessage 校验失败提示
     * @return 可使用的工作流
     * @throws BusinessException 工作流不存在、未启用、跨租户或无使用权限时抛出
     */
    public Workflow requireUsableWorkflow(
            BigInteger workflowId,
            LoginAccount account,
            String denyMessage) {
        String message = denyMessage == null || denyMessage.isBlank()
                ? "工作流不存在、已禁用或无权使用"
                : denyMessage;
        if (workflowId == null || account == null || account.getId() == null
                || account.getTenantId() == null) {
            throw new BusinessException(403, 403, message);
        }
        Workflow workflow = workflowService.getById(workflowId);
        boolean usable = workflow != null
                && Objects.equals(workflow.getTenantId(), account.getTenantId())
                && EnumDataStatus.AVAILABLE.getCode().equals(workflow.getStatus())
                && resourceAccessService.canAccess(
                account,
                CategoryResourceType.WORKFLOW,
                workflow,
                ResourceAction.USE);
        if (!usable) {
            throw new BusinessException(403, 403, message);
        }
        return workflow;
    }
}
