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

import typing

from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.request_options import RequestOptions
from ...types.allowed_countries import AllowedCountries
from ...types.currency_enum import CurrencyEnum
from ...types.entity_bank_account_pagination_response import EntityBankAccountPaginationResponse
from ...types.entity_bank_account_response import EntityBankAccountResponse
from .raw_client import AsyncRawBankAccountsClient, RawBankAccountsClient

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


class BankAccountsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawBankAccountsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawBankAccountsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawBankAccountsClient
        """
        return self._raw_client

    def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> EntityBankAccountPaginationResponse:
        """
        Get all bank accounts of this entity.

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

        Returns
        -------
        EntityBankAccountPaginationResponse
            Successful Response

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.get()
        """
        _response = self._raw_client.get(request_options=request_options)
        return _response.data

    def create(
        self,
        *,
        country: AllowedCountries,
        currency: CurrencyEnum,
        account_holder_name: typing.Optional[str] = OMIT,
        account_number: typing.Optional[str] = OMIT,
        bank_name: typing.Optional[str] = OMIT,
        bic: typing.Optional[str] = OMIT,
        display_name: typing.Optional[str] = OMIT,
        iban: typing.Optional[str] = OMIT,
        is_default_for_currency: typing.Optional[bool] = OMIT,
        routing_number: typing.Optional[str] = OMIT,
        sort_code: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EntityBankAccountResponse:
        """
        Adds a new bank account for the specified entity.

        The minimum required fields are `currency` and `country`. Other required fields depend on the currency and country.

        Bank accounts in African countries can use any fields or combinations of fields.

        For other countries:
        * EUR accounts require `iban`.
        * GBP accounts require `account_holder_name`, `account_number`, and `sort_code`.
        * USD accounts require `account_holder_name`, `account_number`, and `routing_number`.
        * Accounts in other currencies require one of:
          * `iban`
          * `account_number` and `sort_code`
          * `account_number` and `routing_number`

        Parameters
        ----------
        country : AllowedCountries
            The country in which the bank account is registered, repsesented as a two-letter country code ([ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)).

        currency : CurrencyEnum
            The currency of the bank account, represented as a three-letter ISO [currency code](https://docs.monite.com/references/currencies).

        account_holder_name : typing.Optional[str]
            The name of the person or business that owns this bank account. Required in the following cases:
            * the account currency is GBP or USD,
            * the account currency is EUR and the entity wishes to receive SEPA Credit transfers to this account.

        account_number : typing.Optional[str]
            The bank account number. Required if the account currency is GBP or USD. UK account numbers typically contain 8 digits. US bank account numbers contain 9 to 12 digits.

        bank_name : typing.Optional[str]
            The bank name.

        bic : typing.Optional[str]
            The SWIFT/BIC code of the bank. Can be either 8 or 11 characters long. Monite verifies the BIC length, country code, and whether the structure conforms to ISO 9362.

            If `bic` is specified, `iban` must also be specified.

        display_name : typing.Optional[str]
            User-defined name of this bank account, such as 'Primary account' or 'Savings account'.

        iban : typing.Optional[str]
            The IBAN of the bank account, up to 34 characters. Required if the account currency is EUR. Monite verifies the IBAN length, checksum digits, and country-specific format according to ISO 13616.

        is_default_for_currency : typing.Optional[bool]
            If set to `true` or if this is the first bank account added for the given currency, this account becomes the default one for its currency.

        routing_number : typing.Optional[str]
            The bank's routing transit number (RTN) or branch code. Required if the account currency is USD. US routing numbers consist of 9 digits.

        sort_code : typing.Optional[str]
            The bank's sort code. Required if the account currency is GBP.

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.create(country="AF", currency="AED", )
        """
        _response = self._raw_client.create(
            country=country,
            currency=currency,
            account_holder_name=account_holder_name,
            account_number=account_number,
            bank_name=bank_name,
            bic=bic,
            display_name=display_name,
            iban=iban,
            is_default_for_currency=is_default_for_currency,
            routing_number=routing_number,
            sort_code=sort_code,
            request_options=request_options,
        )
        return _response.data

    def get_by_id(
        self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> EntityBankAccountResponse:
        """
        Retrieve a bank account by its ID.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.get_by_id(bank_account_id='bank_account_id', )
        """
        _response = self._raw_client.get_by_id(bank_account_id, request_options=request_options)
        return _response.data

    def delete_by_id(self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete the bank account specified by its ID.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        None

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.delete_by_id(bank_account_id='bank_account_id', )
        """
        _response = self._raw_client.delete_by_id(bank_account_id, request_options=request_options)
        return _response.data

    def update_by_id(
        self,
        bank_account_id: str,
        *,
        account_holder_name: typing.Optional[str] = OMIT,
        display_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EntityBankAccountResponse:
        """
        Change the specified fields with the provided values.

        Parameters
        ----------
        bank_account_id : str

        account_holder_name : typing.Optional[str]
            The name of the person or business that owns this bank account. If the account currency is GBP or USD, the holder name cannot be changed to an empty string.

        display_name : typing.Optional[str]
            User-defined name of this bank account, such as 'Primary account' or 'Savings account'.

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.update_by_id(bank_account_id='bank_account_id', )
        """
        _response = self._raw_client.update_by_id(
            bank_account_id,
            account_holder_name=account_holder_name,
            display_name=display_name,
            request_options=request_options,
        )
        return _response.data

    def make_default_by_id(
        self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> EntityBankAccountResponse:
        """
        Set a bank account as the default for this entity per currency.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import Monite
        client = Monite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        client.entities.bank_accounts.make_default_by_id(bank_account_id='bank_account_id', )
        """
        _response = self._raw_client.make_default_by_id(bank_account_id, request_options=request_options)
        return _response.data


class AsyncBankAccountsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawBankAccountsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawBankAccountsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawBankAccountsClient
        """
        return self._raw_client

    async def get(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> EntityBankAccountPaginationResponse:
        """
        Get all bank accounts of this entity.

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

        Returns
        -------
        EntityBankAccountPaginationResponse
            Successful Response

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.get()
        asyncio.run(main())
        """
        _response = await self._raw_client.get(request_options=request_options)
        return _response.data

    async def create(
        self,
        *,
        country: AllowedCountries,
        currency: CurrencyEnum,
        account_holder_name: typing.Optional[str] = OMIT,
        account_number: typing.Optional[str] = OMIT,
        bank_name: typing.Optional[str] = OMIT,
        bic: typing.Optional[str] = OMIT,
        display_name: typing.Optional[str] = OMIT,
        iban: typing.Optional[str] = OMIT,
        is_default_for_currency: typing.Optional[bool] = OMIT,
        routing_number: typing.Optional[str] = OMIT,
        sort_code: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EntityBankAccountResponse:
        """
        Adds a new bank account for the specified entity.

        The minimum required fields are `currency` and `country`. Other required fields depend on the currency and country.

        Bank accounts in African countries can use any fields or combinations of fields.

        For other countries:
        * EUR accounts require `iban`.
        * GBP accounts require `account_holder_name`, `account_number`, and `sort_code`.
        * USD accounts require `account_holder_name`, `account_number`, and `routing_number`.
        * Accounts in other currencies require one of:
          * `iban`
          * `account_number` and `sort_code`
          * `account_number` and `routing_number`

        Parameters
        ----------
        country : AllowedCountries
            The country in which the bank account is registered, repsesented as a two-letter country code ([ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)).

        currency : CurrencyEnum
            The currency of the bank account, represented as a three-letter ISO [currency code](https://docs.monite.com/references/currencies).

        account_holder_name : typing.Optional[str]
            The name of the person or business that owns this bank account. Required in the following cases:
            * the account currency is GBP or USD,
            * the account currency is EUR and the entity wishes to receive SEPA Credit transfers to this account.

        account_number : typing.Optional[str]
            The bank account number. Required if the account currency is GBP or USD. UK account numbers typically contain 8 digits. US bank account numbers contain 9 to 12 digits.

        bank_name : typing.Optional[str]
            The bank name.

        bic : typing.Optional[str]
            The SWIFT/BIC code of the bank. Can be either 8 or 11 characters long. Monite verifies the BIC length, country code, and whether the structure conforms to ISO 9362.

            If `bic` is specified, `iban` must also be specified.

        display_name : typing.Optional[str]
            User-defined name of this bank account, such as 'Primary account' or 'Savings account'.

        iban : typing.Optional[str]
            The IBAN of the bank account, up to 34 characters. Required if the account currency is EUR. Monite verifies the IBAN length, checksum digits, and country-specific format according to ISO 13616.

        is_default_for_currency : typing.Optional[bool]
            If set to `true` or if this is the first bank account added for the given currency, this account becomes the default one for its currency.

        routing_number : typing.Optional[str]
            The bank's routing transit number (RTN) or branch code. Required if the account currency is USD. US routing numbers consist of 9 digits.

        sort_code : typing.Optional[str]
            The bank's sort code. Required if the account currency is GBP.

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.create(country="AF", currency="AED", )
        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            country=country,
            currency=currency,
            account_holder_name=account_holder_name,
            account_number=account_number,
            bank_name=bank_name,
            bic=bic,
            display_name=display_name,
            iban=iban,
            is_default_for_currency=is_default_for_currency,
            routing_number=routing_number,
            sort_code=sort_code,
            request_options=request_options,
        )
        return _response.data

    async def get_by_id(
        self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> EntityBankAccountResponse:
        """
        Retrieve a bank account by its ID.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.get_by_id(bank_account_id='bank_account_id', )
        asyncio.run(main())
        """
        _response = await self._raw_client.get_by_id(bank_account_id, request_options=request_options)
        return _response.data

    async def delete_by_id(
        self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Delete the bank account specified by its ID.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        None

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.delete_by_id(bank_account_id='bank_account_id', )
        asyncio.run(main())
        """
        _response = await self._raw_client.delete_by_id(bank_account_id, request_options=request_options)
        return _response.data

    async def update_by_id(
        self,
        bank_account_id: str,
        *,
        account_holder_name: typing.Optional[str] = OMIT,
        display_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EntityBankAccountResponse:
        """
        Change the specified fields with the provided values.

        Parameters
        ----------
        bank_account_id : str

        account_holder_name : typing.Optional[str]
            The name of the person or business that owns this bank account. If the account currency is GBP or USD, the holder name cannot be changed to an empty string.

        display_name : typing.Optional[str]
            User-defined name of this bank account, such as 'Primary account' or 'Savings account'.

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.update_by_id(bank_account_id='bank_account_id', )
        asyncio.run(main())
        """
        _response = await self._raw_client.update_by_id(
            bank_account_id,
            account_holder_name=account_holder_name,
            display_name=display_name,
            request_options=request_options,
        )
        return _response.data

    async def make_default_by_id(
        self, bank_account_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> EntityBankAccountResponse:
        """
        Set a bank account as the default for this entity per currency.

        Parameters
        ----------
        bank_account_id : str

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

        Returns
        -------
        EntityBankAccountResponse
            Successful Response

        Examples
        --------
        from monite import AsyncMonite
        import asyncio
        client = AsyncMonite(monite_version="YOUR_MONITE_VERSION", monite_entity_id="YOUR_MONITE_ENTITY_ID", token="YOUR_TOKEN", )
        async def main() -> None:
            await client.entities.bank_accounts.make_default_by_id(bank_account_id='bank_account_id', )
        asyncio.run(main())
        """
        _response = await self._raw_client.make_default_by_id(bank_account_id, request_options=request_options)
        return _response.data
