"""Helpers for API Gateway Lambda proxy responses."""

from __future__ import annotations

import json
from http import HTTPStatus
from typing import Any, Mapping

from aws_lambda_typing.responses import APIGatewayProxyResponseV1

DEFAULT_CORS_HEADERS: dict[str, str] = {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Headers": "*",
    "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS",
}


def _with_cors(base: Mapping[str, str] | None = None) -> dict[str, str]:
    headers = dict(DEFAULT_CORS_HEADERS)
    if base:
        headers.update(base)
    return headers


def _response(
    status_code: int,
    body: Any,
    *,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return {
        "statusCode": status_code,
        "headers": _with_cors({"Content-Type": "application/json", **(headers or {})}),
        "multiValueHeaders": {},
        "body": json.dumps(body),
        "isBase64Encoded": False,
    }


def _error(
    status_code: int,
    message: str,
    *,
    code: str,
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _response(
        status_code,
        {"code": code, "message": message, "details": details},
        headers=headers,
    )


def bad_request(
    message: str,
    *,
    code: str = "BadRequest",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.BAD_REQUEST, message, code=code, details=details, headers=headers)


def not_found(
    message: str = "Not Found",
    *,
    code: str = "NotFound",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.NOT_FOUND, message, code=code, details=details, headers=headers)


def unauthorized(
    message: str = "Unauthorized",
    *,
    code: str = "Unauthorized",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.UNAUTHORIZED, message, code=code, details=details, headers=headers)


def forbidden(
    message: str = "Forbidden",
    *,
    code: str = "Forbidden",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.FORBIDDEN, message, code=code, details=details, headers=headers)


def feature_disabled(
    message: str = "Feature disabled",
    *,
    code: str = "FeatureDisabled",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.FORBIDDEN, message, code=code, details=details, headers=headers)


def internal_server_error(
    message: str = "Internal Server Error",
    *,
    code: str = "InternalServerError",
    details: Any = None,
    headers: Mapping[str, str] | None = None,
) -> APIGatewayProxyResponseV1:
    return _error(HTTPStatus.INTERNAL_SERVER_ERROR, message, code=code, details=details, headers=headers)


__all__ = [
    "DEFAULT_CORS_HEADERS",
    "bad_request",
    "feature_disabled",
    "forbidden",
    "internal_server_error",
    "not_found",
    "unauthorized",
]
