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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.error_response import ErrorResponse
from .types.get_vendors_id_response import GetVendorsIdResponse
from .types.get_vendors_root_response import GetVendorsRootResponse
from .types.post_vendors_bulk_request_vendors_item import PostVendorsBulkRequestVendorsItem
from .types.post_vendors_bulk_response import PostVendorsBulkResponse
from .types.post_vendors_root_request_payment_method import PostVendorsRootRequestPaymentMethod
from .types.post_vendors_root_response import PostVendorsRootResponse

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


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

    def get_vendors_root(
        self,
        *,
        ottimate_company_id: typing.Optional[int] = None,
        detail: typing.Optional[typing.Literal["basic"]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[GetVendorsRootResponse]:
        """
        Returns a paginated list of accounting vendors, filterable by company. The `detail=basic` query parameter returns a simplified response.

        Parameters
        ----------
        ottimate_company_id : typing.Optional[int]
            Filter vendors by company ID

        detail : typing.Optional[typing.Literal["basic"]]
            Specify the level of detail in the response

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

        Returns
        -------
        HttpResponse[GetVendorsRootResponse]
            Successful response with paginated vendor list
        """
        _response = self._client_wrapper.httpx_client.request(
            "vendors",
            method="GET",
            params={
                "ottimate_company_id": ottimate_company_id,
                "detail": detail,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetVendorsRootResponse,
                    parse_obj_as(
                        type_=GetVendorsRootResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def post_vendors_root(
        self,
        *,
        ottimate_company_id: int,
        erp_vendor_name: str,
        erp_vendor_id: str,
        email: typing.Optional[str] = OMIT,
        phone: typing.Optional[str] = OMIT,
        net_terms: typing.Optional[str] = OMIT,
        payment_method: typing.Optional[PostVendorsRootRequestPaymentMethod] = OMIT,
        city: typing.Optional[str] = OMIT,
        state: typing.Optional[str] = OMIT,
        zipcode: typing.Optional[str] = OMIT,
        address_line1: typing.Optional[str] = OMIT,
        address_line2: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PostVendorsRootResponse]:
        """
        Creates a new vendor with the provided details. The `erp_vendor_id` is required and will be mapped to both `accounting_id` and `dd_unique_key`.

        Parameters
        ----------
        ottimate_company_id : int

        erp_vendor_name : str

        erp_vendor_id : str

        email : typing.Optional[str]

        phone : typing.Optional[str]

        net_terms : typing.Optional[str]

        payment_method : typing.Optional[PostVendorsRootRequestPaymentMethod]
            (Optional) Vendor payment method

        city : typing.Optional[str]
            (Optional) Vendor city

        state : typing.Optional[str]
            (Optional) Vendor state

        zipcode : typing.Optional[str]
            (Optional) Vendor zipcode

        address_line1 : typing.Optional[str]
            (Optional) Vendor address line 1

        address_line2 : typing.Optional[str]
            (Optional) Vendor address line 2

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

        Returns
        -------
        HttpResponse[PostVendorsRootResponse]
            Successfully created
        """
        _response = self._client_wrapper.httpx_client.request(
            "vendors",
            method="POST",
            json={
                "ottimate_company_id": ottimate_company_id,
                "erp_vendor_name": erp_vendor_name,
                "erp_vendor_id": erp_vendor_id,
                "email": email,
                "phone": phone,
                "net_terms": net_terms,
                "payment_method": payment_method,
                "city": city,
                "state": state,
                "zipcode": zipcode,
                "address_line_1": address_line1,
                "address_line_2": address_line2,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PostVendorsRootResponse,
                    parse_obj_as(
                        type_=PostVendorsRootResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_vendors_id(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetVendorsIdResponse]:
        """
        Returns detailed information for a single accounting vendor using its unique ID.

        Parameters
        ----------
        id : str
            The unique ID of the vendor

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

        Returns
        -------
        HttpResponse[GetVendorsIdResponse]
            Successful response with vendor details
        """
        _response = self._client_wrapper.httpx_client.request(
            f"vendors/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetVendorsIdResponse,
                    parse_obj_as(
                        type_=GetVendorsIdResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def post_vendors_bulk(
        self,
        *,
        ottimate_company_id: int,
        vendors: typing.Optional[typing.Sequence[PostVendorsBulkRequestVendorsItem]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PostVendorsBulkResponse]:
        """
        Allows for the creation or updating of multiple vendors in a single request. Maximum 100 vendors per request.

        Parameters
        ----------
        ottimate_company_id : int

        vendors : typing.Optional[typing.Sequence[PostVendorsBulkRequestVendorsItem]]

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

        Returns
        -------
        HttpResponse[PostVendorsBulkResponse]
            Successfully created or updated
        """
        _response = self._client_wrapper.httpx_client.request(
            "vendors/bulk",
            method="POST",
            json={
                "ottimate_company_id": ottimate_company_id,
                "vendors": convert_and_respect_annotation_metadata(
                    object_=vendors, annotation=typing.Sequence[PostVendorsBulkRequestVendorsItem], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PostVendorsBulkResponse,
                    parse_obj_as(
                        type_=PostVendorsBulkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def get_vendors_root(
        self,
        *,
        ottimate_company_id: typing.Optional[int] = None,
        detail: typing.Optional[typing.Literal["basic"]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[GetVendorsRootResponse]:
        """
        Returns a paginated list of accounting vendors, filterable by company. The `detail=basic` query parameter returns a simplified response.

        Parameters
        ----------
        ottimate_company_id : typing.Optional[int]
            Filter vendors by company ID

        detail : typing.Optional[typing.Literal["basic"]]
            Specify the level of detail in the response

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

        Returns
        -------
        AsyncHttpResponse[GetVendorsRootResponse]
            Successful response with paginated vendor list
        """
        _response = await self._client_wrapper.httpx_client.request(
            "vendors",
            method="GET",
            params={
                "ottimate_company_id": ottimate_company_id,
                "detail": detail,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetVendorsRootResponse,
                    parse_obj_as(
                        type_=GetVendorsRootResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def post_vendors_root(
        self,
        *,
        ottimate_company_id: int,
        erp_vendor_name: str,
        erp_vendor_id: str,
        email: typing.Optional[str] = OMIT,
        phone: typing.Optional[str] = OMIT,
        net_terms: typing.Optional[str] = OMIT,
        payment_method: typing.Optional[PostVendorsRootRequestPaymentMethod] = OMIT,
        city: typing.Optional[str] = OMIT,
        state: typing.Optional[str] = OMIT,
        zipcode: typing.Optional[str] = OMIT,
        address_line1: typing.Optional[str] = OMIT,
        address_line2: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PostVendorsRootResponse]:
        """
        Creates a new vendor with the provided details. The `erp_vendor_id` is required and will be mapped to both `accounting_id` and `dd_unique_key`.

        Parameters
        ----------
        ottimate_company_id : int

        erp_vendor_name : str

        erp_vendor_id : str

        email : typing.Optional[str]

        phone : typing.Optional[str]

        net_terms : typing.Optional[str]

        payment_method : typing.Optional[PostVendorsRootRequestPaymentMethod]
            (Optional) Vendor payment method

        city : typing.Optional[str]
            (Optional) Vendor city

        state : typing.Optional[str]
            (Optional) Vendor state

        zipcode : typing.Optional[str]
            (Optional) Vendor zipcode

        address_line1 : typing.Optional[str]
            (Optional) Vendor address line 1

        address_line2 : typing.Optional[str]
            (Optional) Vendor address line 2

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

        Returns
        -------
        AsyncHttpResponse[PostVendorsRootResponse]
            Successfully created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "vendors",
            method="POST",
            json={
                "ottimate_company_id": ottimate_company_id,
                "erp_vendor_name": erp_vendor_name,
                "erp_vendor_id": erp_vendor_id,
                "email": email,
                "phone": phone,
                "net_terms": net_terms,
                "payment_method": payment_method,
                "city": city,
                "state": state,
                "zipcode": zipcode,
                "address_line_1": address_line1,
                "address_line_2": address_line2,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PostVendorsRootResponse,
                    parse_obj_as(
                        type_=PostVendorsRootResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_vendors_id(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetVendorsIdResponse]:
        """
        Returns detailed information for a single accounting vendor using its unique ID.

        Parameters
        ----------
        id : str
            The unique ID of the vendor

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

        Returns
        -------
        AsyncHttpResponse[GetVendorsIdResponse]
            Successful response with vendor details
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"vendors/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetVendorsIdResponse,
                    parse_obj_as(
                        type_=GetVendorsIdResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def post_vendors_bulk(
        self,
        *,
        ottimate_company_id: int,
        vendors: typing.Optional[typing.Sequence[PostVendorsBulkRequestVendorsItem]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PostVendorsBulkResponse]:
        """
        Allows for the creation or updating of multiple vendors in a single request. Maximum 100 vendors per request.

        Parameters
        ----------
        ottimate_company_id : int

        vendors : typing.Optional[typing.Sequence[PostVendorsBulkRequestVendorsItem]]

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

        Returns
        -------
        AsyncHttpResponse[PostVendorsBulkResponse]
            Successfully created or updated
        """
        _response = await self._client_wrapper.httpx_client.request(
            "vendors/bulk",
            method="POST",
            json={
                "ottimate_company_id": ottimate_company_id,
                "vendors": convert_and_respect_annotation_metadata(
                    object_=vendors, annotation=typing.Sequence[PostVendorsBulkRequestVendorsItem], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PostVendorsBulkResponse,
                    parse_obj_as(
                        type_=PostVendorsBulkResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
