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

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...entity_types.types.bulk_entity_creation_request import BulkEntityCreationRequest
from ...core.request_options import RequestOptions
from ...entity_types.types.bulk_entity_creation_response import BulkEntityCreationResponse
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...core.pydantic_utilities import parse_obj_as
from ...commons.errors.bad_request import BadRequest
from ...commons.errors.unauthorized import Unauthorized
from ...commons.errors.forbidden import Forbidden
from ...commons.errors.not_found import NotFound
from ...commons.errors.conflict import Conflict
from ...commons.errors.internal_server_error import InternalServerError
from ...commons.errors.unimplemented import Unimplemented
from ...core.client_wrapper import AsyncClientWrapper

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


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

    def create(
        self,
        *,
        request: BulkEntityCreationRequest,
        emit_webhooks: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkEntityCreationResponse:
        """
        Create multiple entities in bulk. This endpoint will process synchronously and return a list of entities that were created or failed to create.

        Parameters
        ----------
        request : BulkEntityCreationRequest

        emit_webhooks : typing.Optional[bool]
            If true, webhooks will be emitted for each entity that is created. By default, webhooks are not emitted.

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

        Returns
        -------
        BulkEntityCreationResponse

        Examples
        --------
        from mercoa import Mercoa
        from mercoa.commons import Address, PhoneNumber
        from mercoa.entity_types import (
            BulkConnectedEntity,
            BulkEntityCreationFromObject,
            BusinessProfileRequest,
            Ein,
            EntityCreationRequest,
            ProfileRequest,
            TaxId,
        )

        client = Mercoa(
            token="YOUR_TOKEN",
        )
        client.entity.bulk.create(
            request=BulkEntityCreationFromObject(
                connected_entity=BulkConnectedEntity(
                    id="ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced",
                    link_created_as_payor=False,
                    link_created_as_payee=True,
                ),
                entities=[
                    EntityCreationRequest(
                        is_customer=True,
                        is_payor=True,
                        is_payee=False,
                        account_type="business",
                        foreign_id="MY-DB-ID-12345",
                        profile=ProfileRequest(
                            business=BusinessProfileRequest(
                                email="customer@acme.com",
                                legal_business_name="Acme Inc.",
                                website="http://www.acme.com",
                                business_type="llc",
                                phone=PhoneNumber(
                                    country_code="1",
                                    number="4155551234",
                                ),
                                address=Address(
                                    address_line_1="123 Main St",
                                    address_line_2="Unit 1",
                                    city="San Francisco",
                                    state_or_province="CA",
                                    postal_code="94105",
                                    country="US",
                                ),
                                tax_id=TaxId(
                                    ein=Ein(
                                        number="12-3456789",
                                    ),
                                ),
                            ),
                        ),
                    )
                ],
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "entities",
            method="POST",
            params={
                "emitWebhooks": emit_webhooks,
            },
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return typing.cast(
                BulkEntityCreationResponse,
                parse_obj_as(
                    type_=BulkEntityCreationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def create(
        self,
        *,
        request: BulkEntityCreationRequest,
        emit_webhooks: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkEntityCreationResponse:
        """
        Create multiple entities in bulk. This endpoint will process synchronously and return a list of entities that were created or failed to create.

        Parameters
        ----------
        request : BulkEntityCreationRequest

        emit_webhooks : typing.Optional[bool]
            If true, webhooks will be emitted for each entity that is created. By default, webhooks are not emitted.

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

        Returns
        -------
        BulkEntityCreationResponse

        Examples
        --------
        import asyncio

        from mercoa import AsyncMercoa
        from mercoa.commons import Address, PhoneNumber
        from mercoa.entity_types import (
            BulkConnectedEntity,
            BulkEntityCreationFromObject,
            BusinessProfileRequest,
            Ein,
            EntityCreationRequest,
            ProfileRequest,
            TaxId,
        )

        client = AsyncMercoa(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.entity.bulk.create(
                request=BulkEntityCreationFromObject(
                    connected_entity=BulkConnectedEntity(
                        id="ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced",
                        link_created_as_payor=False,
                        link_created_as_payee=True,
                    ),
                    entities=[
                        EntityCreationRequest(
                            is_customer=True,
                            is_payor=True,
                            is_payee=False,
                            account_type="business",
                            foreign_id="MY-DB-ID-12345",
                            profile=ProfileRequest(
                                business=BusinessProfileRequest(
                                    email="customer@acme.com",
                                    legal_business_name="Acme Inc.",
                                    website="http://www.acme.com",
                                    business_type="llc",
                                    phone=PhoneNumber(
                                        country_code="1",
                                        number="4155551234",
                                    ),
                                    address=Address(
                                        address_line_1="123 Main St",
                                        address_line_2="Unit 1",
                                        city="San Francisco",
                                        state_or_province="CA",
                                        postal_code="94105",
                                        country="US",
                                    ),
                                    tax_id=TaxId(
                                        ein=Ein(
                                            number="12-3456789",
                                        ),
                                    ),
                                ),
                            ),
                        )
                    ],
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "entities",
            method="POST",
            params={
                "emitWebhooks": emit_webhooks,
            },
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return typing.cast(
                BulkEntityCreationResponse,
                parse_obj_as(
                    type_=BulkEntityCreationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)
