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

from __future__ import annotations
from enum import Enum
from gusto_embedded.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict


class AccountType(str, Enum):
    r"""Bank account type"""

    CHECKING = "Checking"
    SAVINGS = "Savings"


class VerificationStatus(str, Enum):
    r"""The verification status of the bank account.

    'awaiting_deposits' means the bank account is just created and money is being transferred.
    'ready_for_verification' means the micro-deposits are completed and the verification process can begin by using the verify endpoint.
    'verified' means the bank account is verified.
    """

    AWAITING_DEPOSITS = "awaiting_deposits"
    READY_FOR_VERIFICATION = "ready_for_verification"
    VERIFIED = "verified"


class VerificationType(str, Enum):
    r"""The verification type of the bank account.

    'bank_deposits' means the bank account is connected by entering routing and accounting numbers and verifying through micro-deposits.
    'plaid' means the bank account is connected through Plaid.
    """

    BANK_DEPOSITS = "bank_deposits"
    PLAID = "plaid"
    PLAID_EXTERNAL = "plaid_external"


class PlaidStatus(str, Enum):
    r"""The Plaid connection status of the bank account. Only applies when verification type is Plaid."""

    CONNECTED = "connected"
    DISCONNECTED = "disconnected"


class CompanyBankAccountTypedDict(TypedDict):
    r"""The company bank account"""

    uuid: str
    r"""UUID of the bank account"""
    company_uuid: NotRequired[str]
    r"""UUID of the company"""
    account_type: NotRequired[AccountType]
    r"""Bank account type"""
    routing_number: NotRequired[str]
    r"""The bank account's routing number"""
    hidden_account_number: NotRequired[str]
    r"""Masked bank account number"""
    verification_status: NotRequired[VerificationStatus]
    r"""The verification status of the bank account.

    'awaiting_deposits' means the bank account is just created and money is being transferred.
    'ready_for_verification' means the micro-deposits are completed and the verification process can begin by using the verify endpoint.
    'verified' means the bank account is verified.
    """
    verification_type: NotRequired[VerificationType]
    r"""The verification type of the bank account.

    'bank_deposits' means the bank account is connected by entering routing and accounting numbers and verifying through micro-deposits.
    'plaid' means the bank account is connected through Plaid.
    """
    plaid_status: NotRequired[Nullable[PlaidStatus]]
    r"""The Plaid connection status of the bank account. Only applies when verification type is Plaid."""
    last_cached_balance: NotRequired[Nullable[str]]
    r"""The last fetch balance for the bank account. Please be aware that this amount does not reflect the most up-to-date balance and only applies when the verification type is Plaid."""
    balance_fetched_date: NotRequired[Nullable[str]]
    r"""The balance fetch date associated with the last_cached_balance. Only applies when verification type is Plaid."""
    name: NotRequired[str]
    r"""Name of bank account"""


class CompanyBankAccount(BaseModel):
    r"""The company bank account"""

    uuid: str
    r"""UUID of the bank account"""

    company_uuid: Optional[str] = None
    r"""UUID of the company"""

    account_type: Optional[AccountType] = None
    r"""Bank account type"""

    routing_number: Optional[str] = None
    r"""The bank account's routing number"""

    hidden_account_number: Optional[str] = None
    r"""Masked bank account number"""

    verification_status: Optional[VerificationStatus] = None
    r"""The verification status of the bank account.

    'awaiting_deposits' means the bank account is just created and money is being transferred.
    'ready_for_verification' means the micro-deposits are completed and the verification process can begin by using the verify endpoint.
    'verified' means the bank account is verified.
    """

    verification_type: Optional[VerificationType] = None
    r"""The verification type of the bank account.

    'bank_deposits' means the bank account is connected by entering routing and accounting numbers and verifying through micro-deposits.
    'plaid' means the bank account is connected through Plaid.
    """

    plaid_status: OptionalNullable[PlaidStatus] = UNSET
    r"""The Plaid connection status of the bank account. Only applies when verification type is Plaid."""

    last_cached_balance: OptionalNullable[str] = UNSET
    r"""The last fetch balance for the bank account. Please be aware that this amount does not reflect the most up-to-date balance and only applies when the verification type is Plaid."""

    balance_fetched_date: OptionalNullable[str] = UNSET
    r"""The balance fetch date associated with the last_cached_balance. Only applies when verification type is Plaid."""

    name: Optional[str] = None
    r"""Name of bank account"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "company_uuid",
            "account_type",
            "routing_number",
            "hidden_account_number",
            "verification_status",
            "verification_type",
            "plaid_status",
            "last_cached_balance",
            "balance_fetched_date",
            "name",
        ]
        nullable_fields = [
            "plaid_status",
            "last_cached_balance",
            "balance_fetched_date",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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
