from ..configuration_errors import FriskConfigurationError
from ..frisk_error import FriskError


class FriskAuthenticationError(FriskError):
    """Raised when authentication fails."""


class FriskInvalidAPIKeyError(FriskAuthenticationError):
    """Raised when the API key is invalid, revoked, or expired."""

    code = "invalid_api_key"
    message = """\
Frisk API key authentication failed.
    The provided API key is invalid, expired, or has been revoked.
    Please verify that you are using a valid Frisk API key.

    You can:
        • Double-check the API key value
        • Regenerate a new API key from the Frisk dashboard
        • Ensure the key matches the correct environment (dev vs prod)
"""


class FriskAPIResponseError(FriskError):
    """Raised when the Frisk API returns an unexpected HTTP response."""


class FriskGenericAPIResponseError(FriskAPIResponseError):
    """Raised when the Frisk API returns an unexpected HTTP response that doesn't fit into any concrete subclass."""

    code = "generic_api_response_error"

    def __init__(self, status_code: int, error_details: str | None = None):
        self.status_code = status_code
        self.error_details = error_details

        details_block = ""
        if error_details:
            details_block = f"\n    Error details:\n        {error_details}"

        self.message = f"""\
Unexpected response from Frisk API.
    Status code: {status_code}.{details_block}

    If this persists, verify your configuration and contact support.\
"""
        super().__init__()


class FriskBadRequestError(FriskAPIResponseError):
    """Raised for HTTP 400 responses from Frisk API."""

    code = "bad_request"
    message = """\
Frisk API returned 400 Bad Request.
    The request was rejected due to invalid parameters or malformed input.
    Please verify your request payload and try again.

    If you believe this is a bug, contact support with request details.\
"""


class FriskForbiddenError(FriskAPIResponseError):
    """Raised for HTTP 403 responses from Frisk API."""

    code = "forbidden"
    message = """\
Frisk API returned 403 Forbidden.
    Your API key is valid, but it does not have permission to perform this action.
    This can also occur if your organization or project is disabled.

    Please verify your permissions and account status.\
"""


class FriskConflictError(FriskAPIResponseError):
    """Raised for HTTP 409 conflict responses from Frisk API."""

    code = "conflict"
    message = """\
Frisk API returned 409 Conflict.
    The request could not be completed due to a conflict with the current state.
    This can happen when creating a resource that already exists, or when state has changed.

    Please retry or reconcile the conflicting state before trying again.\
"""


class FriskPayloadTooLargeError(FriskAPIResponseError):
    """Raised for HTTP 413 payload-too-large responses from Frisk API."""

    code = "payload_too_large"
    message = """\
Frisk API returned 413 Payload Too Large.
    The request payload exceeds the maximum allowed size.

    Please reduce the payload size and try again.\
"""


class FriskUnprocessableEntityError(FriskAPIResponseError):
    """Raised for HTTP 422 validation errors from Frisk API."""

    code = "unprocessable_entity"
    message = """\
Frisk API returned 422 Unprocessable Entity.
    The request was well-formed, but failed validation.
    Please verify required fields and value formats.

    If available, inspect error details returned by the API for field-level feedback.\
"""


class FriskRateLimitError(FriskAPIResponseError):
    """Raised for HTTP 429 rate-limit responses from Frisk API."""

    code = "rate_limited"
    message = """\
Frisk API returned 429 Too Many Requests.
    Your requests are being rate limited.

    Please back off and retry after a short delay.
    If you need higher limits, contact support.\
"""


class FriskInternalServerError(FriskAPIResponseError):
    """Raised for HTTP 500 responses from Frisk API."""

    code = "internal_server_error"
    message = """\
Frisk API returned 500 Internal Server Error.
    An unexpected error occurred on the Frisk service.

    Please retry. If the issue persists, contact support.\
"""


class FriskBadGatewayError(FriskAPIResponseError):
    """Raised for HTTP 502 responses from Frisk API."""

    code = "bad_gateway"
    message = """\
Frisk API returned 502 Bad Gateway.
    The Frisk service received an invalid response from an upstream dependency.

    Please retry. If the issue persists, contact support.\
"""


class FriskServiceUnavailableError(FriskAPIResponseError):
    """Raised for HTTP 503 responses from Frisk API."""

    code = "service_unavailable"
    message = """\
Frisk API returned 503 Service Unavailable.
    The Frisk service is temporarily unavailable (maintenance or overload).

    Please retry after a short delay.\
"""


class FriskGatewayTimeoutError(FriskAPIResponseError):
    """Raised for HTTP 504 responses from Frisk API."""

    code = "gateway_timeout"
    message = """\
Frisk API returned 504 Gateway Timeout.
    The Frisk service did not respond in time (upstream timeout).

    Please retry. If the issue persists, contact support.\
"""


class FriskBaseURLNotFoundError(FriskConfigurationError):
    """Raised when configured base URL responds with HTTP 404."""

    code = "base_url_not_found"
    message = """\
Frisk base URL returned 404 Not Found.
    The configured Frisk base URL does not appear to be a valid Frisk API endpoint.
    This usually indicates an incorrect or malformed base URL.

    Please verify that:
        • FRISK_BASE_URL points to the Frisk API (not a dashboard or website)
        • The URL includes the correct scheme (https://)
        • There are no extra or missing path segments

    Example:
        export FRISK_BASE_URL="https://api.frisk.ai"
        frisk = Frisk()\
"""


class InvalidAccessTokenError(FriskAuthenticationError):
    """Raised when auth service returns an unusable access token."""

    code = "invalid_access_token"
    message = """\
Invalid access token returned by Frisk authentication service.
    Frisk successfully contacted the authentication service, but the access token
    returned could not be validated by the SDK.

    Please try again. If the issue persists:
        • Verify your system clock is accurate
        • Regenerate your API key
        • Contact support with the time of the failure

    This error does not indicate a problem with your agent code, but prevents
    the SDK from authenticating requests.\
"""


class UnexpectedFriskServerResponseError(FriskError):
    """Raised when API response shape cannot be interpreted by this SDK version."""

    code = "unexpected_server_response"
    message = """\
Unexpected response received from Frisk server.
    The Frisk API responded, but the response could not be interpreted
    by the SDK. This may indicate a temporary service issue or a
    mismatch between SDK and server versions.

    Please try again. If the issue persists:
        • Ensure you are using the latest Frisk SDK version
        • Retry the request after a short delay
        • Contact support with the time of the request

    This error is not caused by your agent configuration or code.\
"""
