"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

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 utils
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from mollie.utils import validate_open_enum
import pydantic
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class ListEntityBalanceCurrency(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 ListEntityBalanceStatus(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The status of the balance."""

    ACTIVE = "active"
    INACTIVE = "inactive"


class ListEntityBalanceTransferFrequency(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 ListEntityBalanceTransferThresholdTypedDict(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 ListEntityBalanceTransferThreshold(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 ListEntityBalanceTransferDestinationTypedDict(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 ListEntityBalanceTransferDestination(BaseModel):
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """

    type: Annotated[
        Optional[BalanceTransferDestinationType],
        PlainValidator(validate_open_enum(False)),
    ] = 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."""


class ListEntityBalanceAvailableAmountTypedDict(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 ListEntityBalanceAvailableAmount(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 ListEntityBalancePendingAmountTypedDict(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 ListEntityBalancePendingAmount(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 ListEntityBalanceLinksTypedDict(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."""


class ListEntityBalanceLinks(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."""


class ListEntityBalanceTypedDict(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: ListEntityBalanceCurrency
    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: ListEntityBalanceStatus
    available_amount: ListEntityBalanceAvailableAmountTypedDict
    r"""The amount directly available on the balance, e.g. `{\"currency\":\"EUR\", \"value\":\"100.00\"}`."""
    pending_amount: ListEntityBalancePendingAmountTypedDict
    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: ListEntityBalanceLinksTypedDict
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""
    transfer_frequency: NotRequired[ListEntityBalanceTransferFrequency]
    transfer_threshold: NotRequired[ListEntityBalanceTransferThresholdTypedDict]
    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[ListEntityBalanceTransferDestinationTypedDict]
    ]
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """


class ListEntityBalance(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: Annotated[Mode, PlainValidator(validate_open_enum(False))]
    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: Annotated[
        ListEntityBalanceCurrency, PlainValidator(validate_open_enum(False))
    ]
    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: Annotated[
        ListEntityBalanceStatus, PlainValidator(validate_open_enum(False))
    ]

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

    pending_amount: Annotated[
        ListEntityBalancePendingAmount, 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[ListEntityBalanceLinks, 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[
        Annotated[
            Optional[ListEntityBalanceTransferFrequency],
            PlainValidator(validate_open_enum(False)),
        ],
        pydantic.Field(alias="transferFrequency"),
    ] = None

    transfer_threshold: Annotated[
        Optional[ListEntityBalanceTransferThreshold],
        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[ListEntityBalanceTransferDestination],
        pydantic.Field(alias="transferDestination"),
    ] = UNSET
    r"""The destination where the available amount will be automatically transferred to according to the configured
    transfer frequency.
    """

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "transferFrequency",
            "transferThreshold",
            "transferReference",
            "transferDestination",
        ]
        nullable_fields = ["transferReference", "transferDestination"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

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

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
