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

from __future__ import annotations
from .transactioncreate import TransactionCreate, TransactionCreateTypedDict
from gr4vy.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from gr4vy.utils import FieldMetadata, HeaderMetadata, RequestMetadata
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class CreateTransactionGlobalsTypedDict(TypedDict):
    merchant_account_id: NotRequired[str]
    r"""The ID of the merchant account to use for this request."""


class CreateTransactionGlobals(BaseModel):
    merchant_account_id: Annotated[
        Optional[str],
        pydantic.Field(alias="x-gr4vy-merchant-account-id"),
        FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
    ] = None
    r"""The ID of the merchant account to use for this request."""


class CreateTransactionRequestTypedDict(TypedDict):
    transaction_create: TransactionCreateTypedDict
    merchant_account_id: NotRequired[str]
    r"""The ID of the merchant account to use for this request."""
    idempotency_key: NotRequired[Nullable[str]]
    r"""A unique key that identifies this request. Providing this header will make this an idempotent request. We recommend using V4 UUIDs, or another random string with enough entropy to avoid collisions."""
    x_forwarded_for: NotRequired[str]
    r"""The IP address to forward from the customer. Use this when calling
    our API from the server side to ensure the customer's address is
    passed to downstream services, rather than your server IP.
    """


class CreateTransactionRequest(BaseModel):
    transaction_create: Annotated[
        TransactionCreate,
        FieldMetadata(request=RequestMetadata(media_type="application/json")),
    ]

    merchant_account_id: Annotated[
        Optional[str],
        pydantic.Field(alias="x-gr4vy-merchant-account-id"),
        FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
    ] = None
    r"""The ID of the merchant account to use for this request."""

    idempotency_key: Annotated[
        OptionalNullable[str],
        pydantic.Field(alias="idempotency-key"),
        FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
    ] = UNSET
    r"""A unique key that identifies this request. Providing this header will make this an idempotent request. We recommend using V4 UUIDs, or another random string with enough entropy to avoid collisions."""

    x_forwarded_for: Annotated[
        Optional[str],
        pydantic.Field(alias="X-Forwarded-For"),
        FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
    ] = None
    r"""The IP address to forward from the customer. Use this when calling
    our API from the server side to ensure the customer's address is
    passed to downstream services, rather than your server IP.
    """

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["merchant_account_id", "idempotency-key", "X-Forwarded-For"]
        nullable_fields = ["idempotency-key"]
        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
