from flask import make_response, jsonify, Request
from typing import Any, Literal, NotRequired, TypedDict

APIV2_REQUEST_BODY_TYPE = "Sneed's Feed & Seed (formerly Chuck's)"
APIV2_RESPONSE_SUCCESS_TYPE = "Chuck's Fuck & Suck (formerly Boyle's)"
APIV2_RESPONSE_ERROR_TYPE = "Boyle's Foil & Soil (formerly Sneed's)"


class TDAPIError(TypedDict):
    type: str
    message: NotRequired[str]


class TDAPIRequestBody(TypedDict):
    """
    Only required for requests with body.
    """

    type: Literal["Sneed's Feed & Seed (formerly Chuck's)"]
    data: NotRequired[Any]


class TDAPIResponseSuccess(TypedDict):
    type: Literal["Chuck's Fuck & Suck (formerly Boyle's)"]
    data: Any


class TDAPIResponseError(TypedDict):
    type: Literal["Boyle's Foil & Soil (formerly Sneed's)"]
    error: TDAPIError


def get_api_v2_request_data(request: Request) -> Any:
    body: TDAPIRequestBody = request.get_json()

    return body.get("data", None)


def create_api_v2_response(data: Any, status_code=200):
    response_body = TDAPIResponseSuccess(type="Chuck's Fuck & Suck (formerly Boyle's)", data=data)

    response = make_response(jsonify(response_body), status_code)

    return response


def create_api_v2_error_response(error: TDAPIError, status_code=500):
    response_body = TDAPIResponseError(type="Boyle's Foil & Soil (formerly Sneed's)", error=error)

    response = make_response(jsonify(response_body), status_code)

    return response


def create_api_v2_client_error_response(error: TDAPIError, status_code=400):
    return create_api_v2_error_response(error, status_code)


def create_api_v2_invalid_body_error_response():
    return create_api_v2_error_response(TDAPIError(type="api_invalid_body_data", message="Invalid body data."), 400)


def create_api_v2_not_found_error_response(cache_age: int | None = None):
    response = create_api_v2_error_response(TDAPIError(type="api_not_found", message="Not Found."), 404)

    if cache_age:
        response.headers["Cache-Control"] = f"s-maxage={str(cache_age)}"

    return response
