"""{{ endpoint.summary }}"""
from http import HTTPStatus
from typing import Any, Dict, List, Optional, Union, cast

import httpx

from ...client import AuthenticatedClient, Client
from ...types import Response, UNSET
from ... import errors

{% for relative in endpoint.relative_imports %}
{{ relative }}
{% endfor %}

{% from "endpoint_macros.py.jinja" import header_params, cookie_params, query_params, json_body, multipart_body,
    arguments, client, kwargs, parse_response, docstring %}

{% set return_string = endpoint.response_type() %}
{% set parsed_responses = (endpoint.responses | length > 0) and return_string != "Any" %}

def _get_kwargs(
    {{ arguments(endpoint, include_client=False) | indent(4) }}
) -> Dict[str, Any]:
    {{ header_params(endpoint) | indent(4) }}

    {{ cookie_params(endpoint) | indent(4) }}

    {{ query_params(endpoint) | indent(4) }}

    {{ json_body(endpoint) | indent(4) }}

    {{ multipart_body(endpoint) | indent(4) }}

    return {
        "method": "{{ endpoint.method }}",
    {% if endpoint.path_parameters %}
        "url": "{{ endpoint.path }}".format(
        {%- for parameter in endpoint.path_parameters.values() -%}
            {{parameter.name}}={{parameter.python_name}},
        {%- endfor -%}
        ),
    {% else %}
        "url": "{{ endpoint.path }}",
    {% endif %}
    {% if endpoint.form_body %}
        "data": form_data.to_dict(),
    {% elif endpoint.multipart_body %}
        "files": {{ "multipart_" + endpoint.multipart_body.python_name }},
    {% elif endpoint.json_body %}
        "json": {{ "json_" + endpoint.json_body.python_name }},
    {% elif endpoint.binary_body %}
        "content": {{ endpoint.binary_body.python_name }}.payload,
    {% endif %}
    {% if endpoint.query_parameters %}
        "params": params,
    {% endif %}
    {% if endpoint.header_parameters or endpoint.binary_body %}
        "headers": headers,
    {% endif %}
    {% if endpoint.cookie_parameters %}
        "cookies": cookies,
    {% endif %}
    }


def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> {{ return_string }}:
    {% for response in endpoint.responses %}
    if response.status_code == HTTPStatus.{{ response.status_code.name }}:
        {% if parsed_responses %}{% import "property_templates/" + response.prop.template as prop_template %}
        {% if prop_template.construct %}
        {{ prop_template.construct(response.prop, response.source.attribute) | indent(8) }}
        {% elif response.source.return_type == response.prop.get_type_string() %}
        {{ response.prop.python_name }} = {{ response.source.attribute }}
        {% else %}
        {{ response.prop.python_name }} = cast({{ response.prop.get_type_string() }}, {{ response.source }})
        {% endif %}
        return {{ response.prop.python_name }}
        {% else %}
        return None
        {% endif %}
    {% endfor %}

    raise errors.UnexpectedStatus(response.status_code, response.content)


def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[{{ return_string }}]:
    return Response(
        status_code=HTTPStatus(response.status_code),
        content=response.content,
        headers=response.headers,
        parsed=_parse_response(client=client, response=response),
    )


def sync_detailed(
    {{ arguments(endpoint) | indent(4) }}
) -> Response[{{ return_string }}]:
    {{ docstring(endpoint, return_string, is_detailed=true) | indent(4) }}

    kwargs = _get_kwargs(
        {{ kwargs(endpoint, include_client=False) }}
    )

    response = client.get_httpx_client().request(
        **kwargs,
    )

    return _build_response(client=client, response=response)

{% if parsed_responses %}
{% set return_without_error = return_string | replace(', ServerError', '') | replace('ServerError, ', '') %}
def sync(
    {{ arguments(endpoint) | indent(4) }}
) -> {{ return_without_error }}:
    {{ docstring(endpoint, return_without_error, is_detailed=false) | indent(4) }}

    response = sync_detailed(
        {{ kwargs(endpoint) }}
    )
    if isinstance(response.parsed, ServerError):
        raise errors.UnexpectedStatus(response.status_code, response.content)

    return response.parsed

{% endif %}

async def asyncio_detailed(
    {{ arguments(endpoint) | indent(4) }}
) -> Response[{{ return_string }}]:
    {{ docstring(endpoint, return_string, is_detailed=true) | indent(4) }}

    kwargs = _get_kwargs(
        {{ kwargs(endpoint, include_client=False) }}
    )

    response = await client.get_async_httpx_client().request(
        **kwargs
    )

    return _build_response(client=client, response=response)

{% if parsed_responses %}
{% set return_without_error = return_string | replace(', ServerError', '') | replace('ServerError, ', '') %}
async def asyncio(
    {{ arguments(endpoint) | indent(4) }}
) -> {{ return_without_error }}:
    {{ docstring(endpoint, return_without_error, is_detailed=false) | indent(4) }}

    response = await asyncio_detailed(
        {{ kwargs(endpoint) }}
    )
    if isinstance(response.parsed, ServerError):
        raise errors.UnexpectedStatus(response.status_code, response.content)

    return response.parsed
{% endif %}
