"""Arcade Starter Tools for Ticktick

DO NOT EDIT THIS MODULE DIRECTLY.

THIS MODULE WAS AUTO-GENERATED BY TRANSPILING THE API STARTER TOOL JSON DEFINITIONS
IN THE ../wrapper_tools DIRECTORY INTO PYTHON CODE. ANY CHANGES TO THIS MODULE WILL
BE OVERWRITTEN BY THE TRANSPILER.
"""

import asyncio
import json
from enum import Enum
from typing import Annotated, Any

import httpx
import jsonschema
from arcade_tdk import ToolContext, tool
from arcade_tdk.auth import OAuth2
from arcade_tdk.errors import RetryableToolError

from .request_body_schemas import REQUEST_BODY_SCHEMAS

# Retry configuration
INITIAL_RETRY_DELAY = 0.5  # seconds

HTTP_CLIENT = httpx.AsyncClient(
    timeout=httpx.Timeout(60.0, connect=10.0),
    limits=httpx.Limits(max_keepalive_connections=20, max_connections=100),
    transport=httpx.AsyncHTTPTransport(retries=3),
    http2=True,
    follow_redirects=True,
)


class ToolMode(str, Enum):
    """Mode for tools with complex request bodies."""

    GET_REQUEST_SCHEMA = "get_request_schema"
    EXECUTE = "execute"


def remove_none_values(data: dict[str, Any]) -> dict[str, Any]:
    return {k: v for k, v in data.items() if v is not None}


async def make_request(
    url: str,
    method: str,
    params: dict[str, Any] | None = None,
    headers: dict[str, Any] | None = None,
    content: str | None = None,
    data: dict[str, Any] | None = None,
    auth: tuple[str, str] | None = None,
    max_retries: int = 3,
) -> httpx.Response:
    """Make an HTTP request with retry logic for 5xx server errors."""
    for attempt in range(max_retries):
        try:
            response = await HTTP_CLIENT.request(
                url=url,
                auth=auth,
                method=method,
                params=params,
                headers=headers,
                content=content,
            )
            response.raise_for_status()
        except httpx.HTTPStatusError as e:
            # Only retry on 5xx server errors
            if e.response.status_code >= 500 and attempt < max_retries - 1:
                # Exponential backoff: 0.5s, 1s, 2s
                await asyncio.sleep(INITIAL_RETRY_DELAY * (2**attempt))
                continue
            # Re-raise for 4xx errors or if max retries reached
            raise
        except httpx.RequestError:
            # Don't retry request errors (network issues are handled by transport)
            raise
        else:
            return response

    # This should never be reached, but satisfies type checker
    raise httpx.RequestError("Max retries exceeded")  # noqa: TRY003


async def make_request_with_schema_validation(
    url: str,
    method: str,
    request_data: dict[str, Any],
    schema: dict[str, Any],
    auth: tuple[str, str] | None = None,
    params: dict[str, Any] | None = None,
    headers: dict[str, Any] | None = None,
    max_retries: int = 3,
) -> httpx.Response:
    """Make an HTTP request with schema validation on format errors."""
    try:
        response = await make_request(
            url=url,
            auth=auth,
            method=method,
            params=params,
            headers=headers,
            content=json.dumps(request_data),
            max_retries=max_retries,
        )
    except httpx.HTTPStatusError as e:
        # Only provide schema validation for format-related errors
        if e.response.status_code in (400, 422):
            # Run validation to provide additional context
            is_valid, validation_error = validate_json_against_schema(request_data, schema)

            api_error_details = f"API returned {e.response.status_code}: {e.response.text}"

            if not is_valid:
                # Schema validation found issues - additional context
                additional_context = (
                    f"{api_error_details}\n\n"
                    f"Schema validation found the following issues:\n"
                    f"{validation_error}"
                )
            else:
                # Schema validation passed - just show API error
                additional_context = api_error_details

            raise RetryableToolError(
                message=(f"API request failed with validation error: {e.response.status_code}"),
                developer_message=api_error_details,
                additional_prompt_content=additional_context,
            ) from e
        else:
            # For non-validation errors, re-raise as-is
            raise
    else:
        return response


def validate_json_against_schema(
    json_data: dict[str, Any], schema: dict[str, Any]
) -> tuple[bool, str | None]:
    """Validate JSON data against an OpenAPI/JSON Schema.

    This provides full JSON Schema Draft 7 validation including:
    - Required fields, types, enums
    - Pattern validation (regex)
    - Format validation (email, uuid, date-time, etc.)
    - Min/max length and values
    - oneOf, anyOf, allOf
    - And all other JSON Schema features

    Args:
        json_data: The JSON data to validate
        schema: The JSON Schema to validate against

    Returns:
        Tuple of (is_valid, error_messages). If valid, error_messages is None.
        If invalid, error_messages contains all validation errors.
    """
    try:
        validator = jsonschema.Draft7Validator(
            schema, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER
        )
        # Collect ALL validation errors
        errors = list(validator.iter_errors(json_data))
        if errors:
            # Format all errors with their paths
            error_messages = []
            for error in errors:
                error_path = ".".join(str(p) for p in error.path) if error.path else "root"
                error_messages.append(f"{error.message} at {error_path}")
            # Join all errors with newlines
            return False, "\n".join(error_messages)
        else:
            return True, None
    except jsonschema.SchemaError as e:
        return False, f"Invalid schema: {e.message}"
    except Exception as e:
        return False, f"Validation error: {e!s}"


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:read"]))
async def retrieve_task_details(
    context: ToolContext,
    project_identifier: Annotated[
        str, "The unique ID of the project containing the task to retrieve."
    ],
    task_identifier: Annotated[
        str,
        "Unique identifier for the task to retrieve detailed information including subtasks and reminders.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTaskById'."]:
    """Retrieve detailed information for a specific task.

    Use this tool to get detailed information about a task by providing the project ID and task ID. It returns information including subtasks, reminders, and scheduling details."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}/task/{taskId}".format(  # noqa: UP032
            projectId=project_identifier, taskId=task_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def delete_specific_task(
    context: ToolContext,
    project_id: Annotated[str, "The unique ID of the project containing the task to be deleted."],
    task_identifier_to_delete: Annotated[
        str, "The unique ID of the task to permanently delete from a project."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTask'."]:
    """Permanently delete a task using project and task IDs.

    This tool is used to permanently remove a specific task by providing its project ID and task ID from Ticktick. Use this when you need to delete a task and ensure it is no longer available in the project."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}/task/{taskId}".format(  # noqa: UP032
            projectId=project_id, taskId=task_identifier_to_delete
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def create_task_ticktick(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createTask'."]:
    """Create a new task in Ticktick with specified properties.

    Use this tool to create a new task in Ticktick by specifying title, content, dates, reminders, subtasks, and the project it belongs to.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CREATETASKTICKTICK"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATETASKTICKTICK"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATETASKTICKTICK"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.ticktick.com/open/v1/task",
        method="POST",
        request_data=request_data,
        schema=json.loads(REQUEST_BODY_SCHEMAS["CREATETASKTICKTICK"]),
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def update_task_properties(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    task_identifier: Annotated[
        str | None,
        "The unique ID of the task to update in Ticktick. This is required to identify the specific task to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateTask'."]:
    """Update a task's properties in Ticktick.

    Use this tool to update various properties of a task in Ticktick. It requires the task ID and project ID, while other fields are optional. Ideal for modifying task details such as status, title, or due date.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATETASKPROPERTIES"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not task_identifier:
        missing_params.append(("task_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join([f"{p[0]} ({p[1]})" for p in missing_params])
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(f"Required parameters validation failed: {param_details}"),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATETASKPROPERTIES"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATETASKPROPERTIES"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.ticktick.com/open/v1/task/{taskId}".format(taskId=task_identifier),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=json.loads(REQUEST_BODY_SCHEMAS["UPDATETASKPROPERTIES"]),
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def mark_task_complete(
    context: ToolContext,
    project_id: Annotated[str, "Unique ID of the project containing the task to be completed."],
    task_identifier: Annotated[str, "The unique ID of the task to be marked as completed."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'completeTask'."]:
    """Marks a specific task as completed in Ticktick.

    Use this tool to mark a task as completed in Ticktick, updating its status and setting the completion time."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}/task/{taskId}/complete".format(  # noqa: UP032
            projectId=project_id, taskId=task_identifier
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:read"]))
async def get_user_projects(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserProjects'."]:
    """Retrieve all user-accessible projects from Ticktick.

    This tool fetches a list of all projects that the authenticated user has access to in Ticktick. It should be called when a user wants to view or manage their projects within the platform."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def create_project_in_ticktick(
    context: ToolContext,
    project_name: Annotated[str, "Name of the project to be created. This is a required field."],
    project_color: Annotated[
        str | None, "Hex color code representing the project's color (e.g., '#F18181')."
    ] = None,
    project_kind: Annotated[
        str | None,
        "Specifies the type of items the project will store. Choose 'TASK' for tasks or 'NOTE' for notes.",  # noqa: E501
    ] = None,
    project_sort_order: Annotated[
        int | None, "The integer value representing the project's sort order."
    ] = None,
    project_view_mode: Annotated[
        str | None, "The display mode for the project: choose from 'list', 'kanban', or 'timeline'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createProject'."]:
    """Create a new project in Ticktick with optional properties.

    Use this tool to create a new project in Ticktick. You can specify the project's name and other optional properties such as color, sort order, view mode, and kind (TASK or NOTE)."""  # noqa: E501
    request_data = remove_none_values({
        "name": project_name,
        "color": project_color,
        "sortOrder": project_sort_order,
        "viewMode": project_view_mode,
        "kind": project_kind,
    })
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:read"]))
async def get_ticktick_project_by_id(
    context: ToolContext,
    project_id: Annotated[str, "The unique ID of the Ticktick project to retrieve."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getProjectById'."]:
    """Retrieve Ticktick project details by project ID.

    This tool retrieves detailed information about a specific project in Ticktick using its ID. It provides the project's name, color, view mode, and kind."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}".format(projectId=project_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def update_project_properties(
    context: ToolContext,
    project_identifier: Annotated[str, "Unique ID of the project to update."],
    project_color: Annotated[
        str | None, "Hex color code representing the color of the project, such as '#FFFFFF'."
    ] = None,
    project_kind: Annotated[str | None, "Specify the type of project: TASK or NOTE."] = None,
    project_name: Annotated[
        str | None,
        "The new name for the project to be updated. This should be a string representing the desired project name.",  # noqa: E501
    ] = None,
    project_sort_order: Annotated[
        int | None,
        "Sort order value for the project, default is 0. Determines the project's position relative to others.",  # noqa: E501
    ] = None,
    project_view_mode: Annotated[
        str | None,
        "Specifies the view mode of the project. Options are 'list', 'kanban', or 'timeline'.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateProject'."]:
    """Update properties of an existing project.

    This tool updates various properties of an existing project, such as name, color, sort order, view mode, and kind. It should be used when changes to these attributes are needed for a project on Ticktick."""  # noqa: E501
    request_data = remove_none_values({
        "name": project_name,
        "color": project_color,
        "sortOrder": project_sort_order,
        "viewMode": project_view_mode,
        "kind": project_kind,
    })
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}".format(  # noqa: UP032
            projectId=project_identifier
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:write"]))
async def delete_ticktick_project(
    context: ToolContext,
    project_id: Annotated[
        str,
        "The unique ID of the Ticktick project to permanently delete. Ensure the ID is correct, as this action cannot be undone.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteProject'."]:
    """Permanently delete a project in Ticktick by ID.

    Use this tool to permanently remove a specific project and all associated tasks from Ticktick by providing the project's ID. Ensure you no longer need the project, as this action cannot be undone."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}".format(projectId=project_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-ticktick", scopes=["tasks:read"]))
async def retrieve_project_with_tasks(
    context: ToolContext,
    project_id: Annotated[
        str, "The unique ID of the project to retrieve with all data, including tasks and columns."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getProjectWithData'."]:
    """Retrieve detailed project information and all related tasks.

    Call this tool to get a complete view of a project, including tasks and column configurations, especially useful for understanding project status and organization."""  # noqa: E501
    request_data = remove_none_values({})
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="https://api.ticktick.com/open/v1/project/{projectId}/data".format(  # noqa: UP032
            projectId=project_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}
