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

from __future__ import annotations
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from dub.utils import FieldMetadata, PathParamMetadata, RequestMetadata
from enum import Enum
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class Status(str, Enum):
    r"""Useful for marking a commission as refunded, duplicate, canceled, or fraudulent. Takes precedence over `amount` and `modifyAmount`. When a commission is marked as refunded, duplicate, canceled, or fraudulent, it will be omitted from the payout, and the payout amount will be recalculated accordingly. Paid commissions cannot be updated."""

    REFUNDED = "refunded"
    DUPLICATE = "duplicate"
    CANCELED = "canceled"
    FRAUD = "fraud"


class UpdateCommissionRequestBodyTypedDict(TypedDict):
    amount: NotRequired[float]
    r"""The new absolute amount for the sale. Paid commissions cannot be updated."""
    modify_amount: NotRequired[float]
    r"""Modify the current sale amount: use positive values to increase the amount, negative values to decrease it. Takes precedence over `amount`. Paid commissions cannot be updated."""
    currency: NotRequired[str]
    r"""The currency of the sale amount to update. Accepts ISO 4217 currency codes."""
    status: NotRequired[Status]
    r"""Useful for marking a commission as refunded, duplicate, canceled, or fraudulent. Takes precedence over `amount` and `modifyAmount`. When a commission is marked as refunded, duplicate, canceled, or fraudulent, it will be omitted from the payout, and the payout amount will be recalculated accordingly. Paid commissions cannot be updated."""


class UpdateCommissionRequestBody(BaseModel):
    amount: Optional[float] = None
    r"""The new absolute amount for the sale. Paid commissions cannot be updated."""

    modify_amount: Annotated[Optional[float], pydantic.Field(alias="modifyAmount")] = (
        None
    )
    r"""Modify the current sale amount: use positive values to increase the amount, negative values to decrease it. Takes precedence over `amount`. Paid commissions cannot be updated."""

    currency: Optional[str] = "usd"
    r"""The currency of the sale amount to update. Accepts ISO 4217 currency codes."""

    status: Optional[Status] = None
    r"""Useful for marking a commission as refunded, duplicate, canceled, or fraudulent. Takes precedence over `amount` and `modifyAmount`. When a commission is marked as refunded, duplicate, canceled, or fraudulent, it will be omitted from the payout, and the payout amount will be recalculated accordingly. Paid commissions cannot be updated."""


class UpdateCommissionRequestTypedDict(TypedDict):
    id: str
    r"""The commission's unique ID on Dub."""
    request_body: NotRequired[UpdateCommissionRequestBodyTypedDict]


class UpdateCommissionRequest(BaseModel):
    id: Annotated[
        str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
    ]
    r"""The commission's unique ID on Dub."""

    request_body: Annotated[
        Optional[UpdateCommissionRequestBody],
        FieldMetadata(request=RequestMetadata(media_type="application/json")),
    ] = None


class UpdateCommissionType(str, Enum):
    CLICK = "click"
    LEAD = "lead"
    SALE = "sale"
    CUSTOM = "custom"


class UpdateCommissionStatus(str, Enum):
    PENDING = "pending"
    PROCESSED = "processed"
    PAID = "paid"
    REFUNDED = "refunded"
    DUPLICATE = "duplicate"
    FRAUD = "fraud"
    CANCELED = "canceled"


class UpdateCommissionResponseBodyTypedDict(TypedDict):
    r"""The updated commission."""

    id: str
    r"""The commission's unique ID on Dub."""
    amount: float
    earnings: float
    currency: str
    status: UpdateCommissionStatus
    created_at: str
    updated_at: str
    type: NotRequired[UpdateCommissionType]
    invoice_id: NotRequired[Nullable[str]]
    description: NotRequired[Nullable[str]]


class UpdateCommissionResponseBody(BaseModel):
    r"""The updated commission."""

    id: str
    r"""The commission's unique ID on Dub."""

    amount: float

    earnings: float

    currency: str

    status: UpdateCommissionStatus

    created_at: Annotated[str, pydantic.Field(alias="createdAt")]

    updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]

    type: Optional[UpdateCommissionType] = None

    invoice_id: Annotated[OptionalNullable[str], pydantic.Field(alias="invoiceId")] = (
        UNSET
    )

    description: OptionalNullable[str] = UNSET

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["type", "invoiceId", "description"]
        nullable_fields = ["invoiceId", "description"]
        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
