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

from __future__ import annotations

import typing

import httpx
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .environment import OttimateEnvironment

if typing.TYPE_CHECKING:
    from .accounts.client import AccountsClient, AsyncAccountsClient
    from .batch.client import AsyncBatchClient, BatchClient
    from .catalog.client import AsyncCatalogClient, CatalogClient
    from .dimensions.client import AsyncDimensionsClient, DimensionsClient
    from .invoices.client import AsyncInvoicesClient, InvoicesClient
    from .oauth.client import AsyncOauthClient, OauthClient
    from .purchase_orders.client import AsyncPurchaseOrdersClient, PurchaseOrdersClient
    from .receipts.client import AsyncReceiptsClient, ReceiptsClient
    from .vendors.client import AsyncVendorsClient, VendorsClient


class Ottimate:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : OttimateEnvironment
        The environment to use for requests from the client. from .environment import OttimateEnvironment



        Defaults to OttimateEnvironment.PRODUCTION



    api_key : str
    api_version : typing.Optional[typing.Literal["1.0.0"]]
    api_key : str
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.Client]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from ottimate import Ottimate

    client = Ottimate(
        api_key="YOUR_API_KEY",
        api_version="YOUR_API_VERSION",
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: OttimateEnvironment = OttimateEnvironment.PRODUCTION,
        api_key: str,
        api_version: typing.Optional[typing.Literal["1.0.0"]] = None,
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.Client] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            api_version=api_version,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.Client(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._accounts: typing.Optional[AccountsClient] = None
        self._batch: typing.Optional[BatchClient] = None
        self._catalog: typing.Optional[CatalogClient] = None
        self._dimensions: typing.Optional[DimensionsClient] = None
        self._invoices: typing.Optional[InvoicesClient] = None
        self._oauth: typing.Optional[OauthClient] = None
        self._purchase_orders: typing.Optional[PurchaseOrdersClient] = None
        self._receipts: typing.Optional[ReceiptsClient] = None
        self._vendors: typing.Optional[VendorsClient] = None

    @property
    def accounts(self):
        if self._accounts is None:
            from .accounts.client import AccountsClient  # noqa: E402

            self._accounts = AccountsClient(client_wrapper=self._client_wrapper)
        return self._accounts

    @property
    def batch(self):
        if self._batch is None:
            from .batch.client import BatchClient  # noqa: E402

            self._batch = BatchClient(client_wrapper=self._client_wrapper)
        return self._batch

    @property
    def catalog(self):
        if self._catalog is None:
            from .catalog.client import CatalogClient  # noqa: E402

            self._catalog = CatalogClient(client_wrapper=self._client_wrapper)
        return self._catalog

    @property
    def dimensions(self):
        if self._dimensions is None:
            from .dimensions.client import DimensionsClient  # noqa: E402

            self._dimensions = DimensionsClient(client_wrapper=self._client_wrapper)
        return self._dimensions

    @property
    def invoices(self):
        if self._invoices is None:
            from .invoices.client import InvoicesClient  # noqa: E402

            self._invoices = InvoicesClient(client_wrapper=self._client_wrapper)
        return self._invoices

    @property
    def oauth(self):
        if self._oauth is None:
            from .oauth.client import OauthClient  # noqa: E402

            self._oauth = OauthClient(client_wrapper=self._client_wrapper)
        return self._oauth

    @property
    def purchase_orders(self):
        if self._purchase_orders is None:
            from .purchase_orders.client import PurchaseOrdersClient  # noqa: E402

            self._purchase_orders = PurchaseOrdersClient(client_wrapper=self._client_wrapper)
        return self._purchase_orders

    @property
    def receipts(self):
        if self._receipts is None:
            from .receipts.client import ReceiptsClient  # noqa: E402

            self._receipts = ReceiptsClient(client_wrapper=self._client_wrapper)
        return self._receipts

    @property
    def vendors(self):
        if self._vendors is None:
            from .vendors.client import VendorsClient  # noqa: E402

            self._vendors = VendorsClient(client_wrapper=self._client_wrapper)
        return self._vendors


class AsyncOttimate:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : OttimateEnvironment
        The environment to use for requests from the client. from .environment import OttimateEnvironment



        Defaults to OttimateEnvironment.PRODUCTION



    api_key : str
    api_version : typing.Optional[typing.Literal["1.0.0"]]
    api_key : str
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.AsyncClient]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from ottimate import AsyncOttimate

    client = AsyncOttimate(
        api_key="YOUR_API_KEY",
        api_version="YOUR_API_VERSION",
        api_key="YOUR_API_KEY",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: OttimateEnvironment = OttimateEnvironment.PRODUCTION,
        api_key: str,
        api_version: typing.Optional[typing.Literal["1.0.0"]] = None,
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            api_key=api_key,
            api_version=api_version,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._accounts: typing.Optional[AsyncAccountsClient] = None
        self._batch: typing.Optional[AsyncBatchClient] = None
        self._catalog: typing.Optional[AsyncCatalogClient] = None
        self._dimensions: typing.Optional[AsyncDimensionsClient] = None
        self._invoices: typing.Optional[AsyncInvoicesClient] = None
        self._oauth: typing.Optional[AsyncOauthClient] = None
        self._purchase_orders: typing.Optional[AsyncPurchaseOrdersClient] = None
        self._receipts: typing.Optional[AsyncReceiptsClient] = None
        self._vendors: typing.Optional[AsyncVendorsClient] = None

    @property
    def accounts(self):
        if self._accounts is None:
            from .accounts.client import AsyncAccountsClient  # noqa: E402

            self._accounts = AsyncAccountsClient(client_wrapper=self._client_wrapper)
        return self._accounts

    @property
    def batch(self):
        if self._batch is None:
            from .batch.client import AsyncBatchClient  # noqa: E402

            self._batch = AsyncBatchClient(client_wrapper=self._client_wrapper)
        return self._batch

    @property
    def catalog(self):
        if self._catalog is None:
            from .catalog.client import AsyncCatalogClient  # noqa: E402

            self._catalog = AsyncCatalogClient(client_wrapper=self._client_wrapper)
        return self._catalog

    @property
    def dimensions(self):
        if self._dimensions is None:
            from .dimensions.client import AsyncDimensionsClient  # noqa: E402

            self._dimensions = AsyncDimensionsClient(client_wrapper=self._client_wrapper)
        return self._dimensions

    @property
    def invoices(self):
        if self._invoices is None:
            from .invoices.client import AsyncInvoicesClient  # noqa: E402

            self._invoices = AsyncInvoicesClient(client_wrapper=self._client_wrapper)
        return self._invoices

    @property
    def oauth(self):
        if self._oauth is None:
            from .oauth.client import AsyncOauthClient  # noqa: E402

            self._oauth = AsyncOauthClient(client_wrapper=self._client_wrapper)
        return self._oauth

    @property
    def purchase_orders(self):
        if self._purchase_orders is None:
            from .purchase_orders.client import AsyncPurchaseOrdersClient  # noqa: E402

            self._purchase_orders = AsyncPurchaseOrdersClient(client_wrapper=self._client_wrapper)
        return self._purchase_orders

    @property
    def receipts(self):
        if self._receipts is None:
            from .receipts.client import AsyncReceiptsClient  # noqa: E402

            self._receipts = AsyncReceiptsClient(client_wrapper=self._client_wrapper)
        return self._receipts

    @property
    def vendors(self):
        if self._vendors is None:
            from .vendors.client import AsyncVendorsClient  # noqa: E402

            self._vendors = AsyncVendorsClient(client_wrapper=self._client_wrapper)
        return self._vendors


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: OttimateEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
