"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
# @generated-id: f8cd8041d7fd

from __future__ import annotations
from .balance_transfer_destination_type import BalanceTransferDestinationType
from .mode import Mode
from .url import URL, URLTypedDict
from enum import Enum
from mollie import models, utils
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import field_serializer, model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class EntityBalanceCurrency(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The balance's ISO 4217 currency code."""

    EUR = "EUR"
    GBP = "GBP"
    CHF = "CHF"
    DKK = "DKK"
    NOK = "NOK"
    PLN = "PLN"
    SEK = "SEK"
    USD = "USD"
    CZK = "CZK"
    HUF = "HUF"
    AUD = "AUD"
    CAD = "CAD"


class EntityBalanceStatus(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The status of the balance."""

    ACTIVE = "active"
    INACTIVE = "inactive"


class EntityBalanceTransferFrequency(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The frequency with which the available amount on the balance will be settled to the configured transfer
    destination.

    Settlements created during weekends or on bank holidays will take place on the next business day.
    """

    EVERY_DAY = "every-day"
    DAILY = "daily"
    EVERY_MONDAY = "every-monday"
    EVERY_TUESDAY = "every-tuesday"
    EVERY_WEDNESDAY = "every-wednesday"
    EVERY_THURSDAY = "every-thursday"
    EVERY_FRIDAY = "every-friday"
    MONTHLY = "monthly"
    REVENUE_DAY = "revenue-day"
    NEVER = "never"


class EntityBalanceTransferThresholdTypedDict(TypedDict):
    r"""The minimum amount configured for scheduled automatic settlements. As soon as the amount on the balance exceeds
    this threshold, the complete balance will be paid out to the transfer destination according to the configured
    frequency.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalanceTransferThreshold(BaseModel):
    r"""The minimum amount configured for scheduled automatic settlements. As soon as the amount on the balance exceeds
    this threshold, the complete balance will be paid out to the transfer destination according to the configured
    frequency.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalanceTransferDestinationTypedDict(TypedDict):
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """

    type: NotRequired[BalanceTransferDestinationType]
    r"""The default destination of automatic scheduled transfers. Currently only `bank-account` is supported.

    * `bank-account` — Transfer the balance amount to an external bank account
    """
    bank_account: NotRequired[str]
    r"""The configured bank account number of the beneficiary the balance amount is to be transferred to."""
    beneficiary_name: NotRequired[str]
    r"""The full name of the beneficiary the balance amount is to be transferred to."""


class EntityBalanceTransferDestination(BaseModel):
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """

    type: Optional[BalanceTransferDestinationType] = None
    r"""The default destination of automatic scheduled transfers. Currently only `bank-account` is supported.

    * `bank-account` — Transfer the balance amount to an external bank account
    """

    bank_account: Annotated[Optional[str], pydantic.Field(alias="bankAccount")] = None
    r"""The configured bank account number of the beneficiary the balance amount is to be transferred to."""

    beneficiary_name: Annotated[
        Optional[str], pydantic.Field(alias="beneficiaryName")
    ] = None
    r"""The full name of the beneficiary the balance amount is to be transferred to."""

    @field_serializer("type")
    def serialize_type(self, value):
        if isinstance(value, str):
            try:
                return models.BalanceTransferDestinationType(value)
            except ValueError:
                return value
        return value

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["type", "bankAccount", "beneficiaryName"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))

            if val != UNSET_SENTINEL:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m


class EntityBalanceAvailableAmountTypedDict(TypedDict):
    r"""The amount directly available on the balance, e.g. `{\"currency\":\"EUR\", \"value\":\"100.00\"}`."""

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalanceAvailableAmount(BaseModel):
    r"""The amount directly available on the balance, e.g. `{\"currency\":\"EUR\", \"value\":\"100.00\"}`."""

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalancePendingAmountTypedDict(TypedDict):
    r"""The total amount that is queued to be transferred to your balance. For example, a credit card payment can take a
    few days to clear.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalancePendingAmount(BaseModel):
    r"""The total amount that is queued to be transferred to your balance. For example, a credit card payment can take a
    few days to clear.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class EntityBalanceLinksTypedDict(TypedDict):
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    self_: NotRequired[URLTypedDict]
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""
    documentation: NotRequired[URLTypedDict]
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""


class EntityBalanceLinks(BaseModel):
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    self_: Annotated[Optional[URL], pydantic.Field(alias="self")] = None
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""

    documentation: Optional[URL] = None
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["self", "documentation"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))

            if val != UNSET_SENTINEL:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m


class EntityBalanceTypedDict(TypedDict):
    resource: str
    r"""Indicates the response contains a balance object. Will always contain the string `balance` for this endpoint."""
    id: str
    r"""The identifier uniquely referring to this balance."""
    mode: Mode
    r"""Whether this entity was created in live mode or in test mode."""
    created_at: str
    r"""The entity's date and time of creation, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format."""
    currency: EntityBalanceCurrency
    r"""The balance's ISO 4217 currency code."""
    description: str
    r"""The description or name of the balance. Can be used to denote the purpose of the balance."""
    status: EntityBalanceStatus
    available_amount: EntityBalanceAvailableAmountTypedDict
    r"""The amount directly available on the balance, e.g. `{\"currency\":\"EUR\", \"value\":\"100.00\"}`."""
    pending_amount: EntityBalancePendingAmountTypedDict
    r"""The total amount that is queued to be transferred to your balance. For example, a credit card payment can take a
    few days to clear.
    """
    links: EntityBalanceLinksTypedDict
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""
    transfer_frequency: NotRequired[EntityBalanceTransferFrequency]
    transfer_threshold: NotRequired[EntityBalanceTransferThresholdTypedDict]
    r"""The minimum amount configured for scheduled automatic settlements. As soon as the amount on the balance exceeds
    this threshold, the complete balance will be paid out to the transfer destination according to the configured
    frequency.
    """
    transfer_reference: NotRequired[Nullable[str]]
    r"""The transfer reference set to be included in all the transfers for this balance."""
    transfer_destination: NotRequired[
        Nullable[EntityBalanceTransferDestinationTypedDict]
    ]
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """


class EntityBalance(BaseModel):
    resource: str
    r"""Indicates the response contains a balance object. Will always contain the string `balance` for this endpoint."""

    id: str
    r"""The identifier uniquely referring to this balance."""

    mode: Mode
    r"""Whether this entity was created in live mode or in test mode."""

    created_at: Annotated[str, pydantic.Field(alias="createdAt")]
    r"""The entity's date and time of creation, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format."""

    currency: EntityBalanceCurrency
    r"""The balance's ISO 4217 currency code."""

    description: str
    r"""The description or name of the balance. Can be used to denote the purpose of the balance."""

    status: EntityBalanceStatus

    available_amount: Annotated[
        EntityBalanceAvailableAmount, pydantic.Field(alias="availableAmount")
    ]
    r"""The amount directly available on the balance, e.g. `{\"currency\":\"EUR\", \"value\":\"100.00\"}`."""

    pending_amount: Annotated[
        EntityBalancePendingAmount, pydantic.Field(alias="pendingAmount")
    ]
    r"""The total amount that is queued to be transferred to your balance. For example, a credit card payment can take a
    few days to clear.
    """

    links: Annotated[EntityBalanceLinks, pydantic.Field(alias="_links")]
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    transfer_frequency: Annotated[
        Optional[EntityBalanceTransferFrequency],
        pydantic.Field(alias="transferFrequency"),
    ] = None

    transfer_threshold: Annotated[
        Optional[EntityBalanceTransferThreshold],
        pydantic.Field(alias="transferThreshold"),
    ] = None
    r"""The minimum amount configured for scheduled automatic settlements. As soon as the amount on the balance exceeds
    this threshold, the complete balance will be paid out to the transfer destination according to the configured
    frequency.
    """

    transfer_reference: Annotated[
        OptionalNullable[str], pydantic.Field(alias="transferReference")
    ] = UNSET
    r"""The transfer reference set to be included in all the transfers for this balance."""

    transfer_destination: Annotated[
        OptionalNullable[EntityBalanceTransferDestination],
        pydantic.Field(alias="transferDestination"),
    ] = UNSET
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """

    @field_serializer("mode")
    def serialize_mode(self, value):
        if isinstance(value, str):
            try:
                return models.Mode(value)
            except ValueError:
                return value
        return value

    @field_serializer("currency")
    def serialize_currency(self, value):
        if isinstance(value, str):
            try:
                return models.EntityBalanceCurrency(value)
            except ValueError:
                return value
        return value

    @field_serializer("status")
    def serialize_status(self, value):
        if isinstance(value, str):
            try:
                return models.EntityBalanceStatus(value)
            except ValueError:
                return value
        return value

    @field_serializer("transfer_frequency")
    def serialize_transfer_frequency(self, value):
        if isinstance(value, str):
            try:
                return models.EntityBalanceTransferFrequency(value)
            except ValueError:
                return value
        return value

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "transferFrequency",
                "transferThreshold",
                "transferReference",
                "transferDestination",
            ]
        )
        nullable_fields = set(["transferReference", "transferDestination"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

            if val != UNSET_SENTINEL:
                if (
                    val is not None
                    or k not in optional_fields
                    or is_nullable_and_explicitly_set
                ):
                    m[k] = val

        return m


try:
    EntityBalanceTransferDestination.model_rebuild()
except NameError:
    pass
try:
    EntityBalanceLinks.model_rebuild()
except NameError:
    pass
try:
    EntityBalance.model_rebuild()
except NameError:
    pass
