"""AI 服务异常体系."""

from typing import Any

from .codes import ErrorCode, ErrorCodes


class AIError(Exception):
    """AI 服务基础异常.

    所有 AI 服务异常均携带 ErrorCode + HTTP status + 可选 details.
    """

    def __init__(
        self,
        code: ErrorCode = ErrorCode.AI_INTERNAL_ERROR,
        message: str = "",
        details: dict[str, Any] | None = None,
    ) -> None:
        self.code = code
        self.message = message or code.value
        self.details = details or {}
        self.http_status = ErrorCodes.http_status(code)
        super().__init__(self.message)


class AIValidationError(AIError):
    """输入校验异常."""

    def __init__(self, message: str, details: dict[str, Any] | None = None) -> None:
        super().__init__(ErrorCode.AI_INVALID_MODEL, message, details)


class AIRateLimitedError(AIError):
    """限流异常."""

    def __init__(self, dimension: str, limit: int) -> None:
        super().__init__(
            ErrorCode.AI_RATE_LIMITED,
            f"Rate limit exceeded for {dimension}",
            {"dimension": dimension, "limit": limit},
        )


class AIQuotaExceededError(AIError):
    """配额超限异常."""

    def __init__(self, scope: str, used: int, budget: int) -> None:
        super().__init__(
            ErrorCode.AI_QUOTA_EXCEEDED,
            f"Quota exceeded for {scope}",
            {"scope": scope, "used": used, "budget": budget},
        )


class AILLMUnavailableError(AIError):
    """LLM 不可用异常（触发降级）."""

    def __init__(self, reason: str = "all providers failed") -> None:
        super().__init__(ErrorCode.AI_LLM_UNAVAILABLE, reason)


class AIWorkflowNotFoundError(AIError):
    """工作流不存在."""

    def __init__(self, workflow_id: str) -> None:
        super().__init__(
            ErrorCode.AI_WORKFLOW_NOT_FOUND,
            f"Workflow {workflow_id} not found",
            {"workflow_id": workflow_id},
        )


class AIWorkflowStateInvalidError(AIError):
    """工作流状态不允许此操作."""

    def __init__(self, workflow_id: str, current_status: str, action: str) -> None:
        super().__init__(
            ErrorCode.AI_WORKFLOW_STATE_INVALID,
            f"Cannot {action} workflow {workflow_id} in status {current_status}",
            {"workflow_id": workflow_id, "current_status": current_status, "action": action},
        )
