# This file was auto-generated by Fern from our API Definition.

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...requests.customer_group import CustomerGroupParams
from ...core.request_options import RequestOptions
from ...core.http_response import HttpResponse
from ...types.create_customer_group_response import CreateCustomerGroupResponse
from ...core.serialization import convert_and_respect_annotation_metadata
from ...core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...types.get_customer_group_response import GetCustomerGroupResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...types.update_customer_group_response import UpdateCustomerGroupResponse
from ...types.delete_customer_group_response import DeleteCustomerGroupResponse
from ...types.add_group_to_customer_response import AddGroupToCustomerResponse
from ...types.remove_group_from_customer_response import RemoveGroupFromCustomerResponse
from ...core.client_wrapper import AsyncClientWrapper
from ...core.http_response import AsyncHttpResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawGroupsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        group: CustomerGroupParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateCustomerGroupResponse]:
        """
        Creates a new customer group for a business.

        The request must include the `name` value of the group.

        Parameters
        ----------
        group : CustomerGroupParams
            The customer group to create.

        idempotency_key : typing.Optional[str]
            The idempotency key for the request. For more information, see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CreateCustomerGroupResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/customers/groups",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "group": convert_and_respect_annotation_metadata(
                    object_=group, annotation=CustomerGroupParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateCustomerGroupResponse,
                    construct_type(
                        type_=CreateCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(
        self, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetCustomerGroupResponse]:
        """
        Retrieves a specific customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[GetCustomerGroupResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetCustomerGroupResponse,
                    construct_type(
                        type_=GetCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self, group_id: str, *, group: CustomerGroupParams, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[UpdateCustomerGroupResponse]:
        """
        Updates a customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to update.

        group : CustomerGroupParams
            The `CustomerGroup` object including all the updates you want to make.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpdateCustomerGroupResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="PUT",
            json={
                "group": convert_and_respect_annotation_metadata(
                    object_=group, annotation=CustomerGroupParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateCustomerGroupResponse,
                    construct_type(
                        type_=UpdateCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(
        self, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteCustomerGroupResponse]:
        """
        Deletes a customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DeleteCustomerGroupResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteCustomerGroupResponse,
                    construct_type(
                        type_=DeleteCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def add(
        self, customer_id: str, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[AddGroupToCustomerResponse]:
        """
        Adds a group membership to a customer.

        The customer is identified by the `customer_id` value
        and the customer group is identified by the `group_id` value.

        Parameters
        ----------
        customer_id : str
            The ID of the customer to add to a group.

        group_id : str
            The ID of the customer group to add the customer to.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AddGroupToCustomerResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/customers/{jsonable_encoder(customer_id)}/groups/{jsonable_encoder(group_id)}",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AddGroupToCustomerResponse,
                    construct_type(
                        type_=AddGroupToCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def remove(
        self, customer_id: str, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[RemoveGroupFromCustomerResponse]:
        """
        Removes a group membership from a customer.

        The customer is identified by the `customer_id` value
        and the customer group is identified by the `group_id` value.

        Parameters
        ----------
        customer_id : str
            The ID of the customer to remove from the group.

        group_id : str
            The ID of the customer group to remove the customer from.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[RemoveGroupFromCustomerResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/customers/{jsonable_encoder(customer_id)}/groups/{jsonable_encoder(group_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RemoveGroupFromCustomerResponse,
                    construct_type(
                        type_=RemoveGroupFromCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncRawGroupsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        group: CustomerGroupParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateCustomerGroupResponse]:
        """
        Creates a new customer group for a business.

        The request must include the `name` value of the group.

        Parameters
        ----------
        group : CustomerGroupParams
            The customer group to create.

        idempotency_key : typing.Optional[str]
            The idempotency key for the request. For more information, see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CreateCustomerGroupResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/customers/groups",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "group": convert_and_respect_annotation_metadata(
                    object_=group, annotation=CustomerGroupParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateCustomerGroupResponse,
                    construct_type(
                        type_=CreateCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetCustomerGroupResponse]:
        """
        Retrieves a specific customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to retrieve.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[GetCustomerGroupResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetCustomerGroupResponse,
                    construct_type(
                        type_=GetCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self, group_id: str, *, group: CustomerGroupParams, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[UpdateCustomerGroupResponse]:
        """
        Updates a customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to update.

        group : CustomerGroupParams
            The `CustomerGroup` object including all the updates you want to make.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpdateCustomerGroupResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="PUT",
            json={
                "group": convert_and_respect_annotation_metadata(
                    object_=group, annotation=CustomerGroupParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateCustomerGroupResponse,
                    construct_type(
                        type_=UpdateCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(
        self, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteCustomerGroupResponse]:
        """
        Deletes a customer group as identified by the `group_id` value.

        Parameters
        ----------
        group_id : str
            The ID of the customer group to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DeleteCustomerGroupResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/customers/groups/{jsonable_encoder(group_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteCustomerGroupResponse,
                    construct_type(
                        type_=DeleteCustomerGroupResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def add(
        self, customer_id: str, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[AddGroupToCustomerResponse]:
        """
        Adds a group membership to a customer.

        The customer is identified by the `customer_id` value
        and the customer group is identified by the `group_id` value.

        Parameters
        ----------
        customer_id : str
            The ID of the customer to add to a group.

        group_id : str
            The ID of the customer group to add the customer to.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AddGroupToCustomerResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/customers/{jsonable_encoder(customer_id)}/groups/{jsonable_encoder(group_id)}",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AddGroupToCustomerResponse,
                    construct_type(
                        type_=AddGroupToCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def remove(
        self, customer_id: str, group_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[RemoveGroupFromCustomerResponse]:
        """
        Removes a group membership from a customer.

        The customer is identified by the `customer_id` value
        and the customer group is identified by the `group_id` value.

        Parameters
        ----------
        customer_id : str
            The ID of the customer to remove from the group.

        group_id : str
            The ID of the customer group to remove the customer from.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[RemoveGroupFromCustomerResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/customers/{jsonable_encoder(customer_id)}/groups/{jsonable_encoder(group_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RemoveGroupFromCustomerResponse,
                    construct_type(
                        type_=RemoveGroupFromCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
