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

from __future__ import annotations
from .currency import Currency
from .custommappings import CustomMappings, CustomMappingsTypedDict
from .passthroughbody import PassThroughBody, PassThroughBodyTypedDict
from apideck_unify.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from datetime import datetime
from enum import Enum
import pydantic
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class MessageType(str, Enum):
    r"""Set to sms for SMS messages and mms for MMS messages."""

    SMS = "sms"
    MMS = "mms"


class Direction(str, Enum):
    r"""The direction of the message."""

    INBOUND = "inbound"
    OUTBOUND_API = "outbound-api"
    OUTBOUND_CALL = "outbound-call"
    OUTBOUND_REPLY = "outbound-reply"
    UNKNOWN = "unknown"


class MessageStatus(str, Enum):
    r"""Status of the delivery of the message."""

    ACCEPTED = "accepted"
    SCHEDULED = "scheduled"
    CANCELED = "canceled"
    QUEUED = "queued"
    SENDING = "sending"
    SENT = "sent"
    FAILED = "failed"
    DELIVERED = "delivered"
    UNDELIVERED = "undelivered"
    RECEIVING = "receiving"
    RECEIVED = "received"
    READ = "read"


class PriceTypedDict(TypedDict):
    r"""Price of the message."""

    per_unit: NotRequired[str]
    total_amount: NotRequired[str]
    currency: NotRequired[Nullable[Currency]]
    r"""Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)."""


class Price(BaseModel):
    r"""Price of the message."""

    per_unit: Optional[str] = None

    total_amount: Optional[str] = None

    currency: OptionalNullable[Currency] = UNSET
    r"""Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)."""

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


class ErrorTypedDict(TypedDict):
    r"""The error returned if your message status is failed or undelivered."""

    code: NotRequired[str]
    r"""The error_code provides more information about the failure. If the message was successful, this value is null"""
    message: NotRequired[str]


class Error(BaseModel):
    r"""The error returned if your message status is failed or undelivered."""

    code: Optional[str] = None
    r"""The error_code provides more information about the failure. If the message was successful, this value is null"""

    message: Optional[str] = None


class MessageTypedDict(TypedDict):
    from_: str
    r"""The phone number that initiated the message."""
    to: str
    r"""The phone number that received the message."""
    body: str
    r"""The message text."""
    id: NotRequired[str]
    r"""A unique identifier for an object."""
    subject: NotRequired[str]
    type: NotRequired[MessageType]
    r"""Set to sms for SMS messages and mms for MMS messages."""
    number_of_units: NotRequired[int]
    r"""The number of units that make up the complete message. Messages can be split up due to the constraints of the message size."""
    number_of_media_files: NotRequired[int]
    r"""The number of media files associated with the message."""
    direction: NotRequired[Direction]
    r"""The direction of the message."""
    status: NotRequired[MessageStatus]
    r"""Status of the delivery of the message."""
    scheduled_at: NotRequired[datetime]
    r"""The scheduled date and time of the message."""
    sent_at: NotRequired[datetime]
    r"""The date and time that the message was sent"""
    webhook_url: NotRequired[str]
    r"""Define a webhook to receive delivery notifications."""
    reference: NotRequired[str]
    r"""A client reference."""
    price: NotRequired[PriceTypedDict]
    r"""Price of the message."""
    error: NotRequired[ErrorTypedDict]
    r"""The error returned if your message status is failed or undelivered."""
    messaging_service_id: NotRequired[str]
    r"""The ID of the Messaging Service used with the message. In case of Plivo this links to the Powerpack ID."""
    custom_mappings: NotRequired[Nullable[CustomMappingsTypedDict]]
    r"""When custom mappings are configured on the resource, the result is included here."""
    updated_by: NotRequired[Nullable[str]]
    r"""The user who last updated the object."""
    created_by: NotRequired[Nullable[str]]
    r"""The user who created the object."""
    updated_at: NotRequired[Nullable[datetime]]
    r"""The date and time when the object was last updated."""
    created_at: NotRequired[Nullable[datetime]]
    r"""The date and time when the object was created."""
    pass_through: NotRequired[List[PassThroughBodyTypedDict]]
    r"""The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources."""


class Message(BaseModel):
    from_: Annotated[str, pydantic.Field(alias="from")]
    r"""The phone number that initiated the message."""

    to: str
    r"""The phone number that received the message."""

    body: str
    r"""The message text."""

    id: Optional[str] = None
    r"""A unique identifier for an object."""

    subject: Optional[str] = None

    type: Optional[MessageType] = None
    r"""Set to sms for SMS messages and mms for MMS messages."""

    number_of_units: Optional[int] = None
    r"""The number of units that make up the complete message. Messages can be split up due to the constraints of the message size."""

    number_of_media_files: Optional[int] = None
    r"""The number of media files associated with the message."""

    direction: Optional[Direction] = None
    r"""The direction of the message."""

    status: Optional[MessageStatus] = None
    r"""Status of the delivery of the message."""

    scheduled_at: Optional[datetime] = None
    r"""The scheduled date and time of the message."""

    sent_at: Optional[datetime] = None
    r"""The date and time that the message was sent"""

    webhook_url: Optional[str] = None
    r"""Define a webhook to receive delivery notifications."""

    reference: Optional[str] = None
    r"""A client reference."""

    price: Optional[Price] = None
    r"""Price of the message."""

    error: Optional[Error] = None
    r"""The error returned if your message status is failed or undelivered."""

    messaging_service_id: Optional[str] = None
    r"""The ID of the Messaging Service used with the message. In case of Plivo this links to the Powerpack ID."""

    custom_mappings: OptionalNullable[CustomMappings] = UNSET
    r"""When custom mappings are configured on the resource, the result is included here."""

    updated_by: OptionalNullable[str] = UNSET
    r"""The user who last updated the object."""

    created_by: OptionalNullable[str] = UNSET
    r"""The user who created the object."""

    updated_at: OptionalNullable[datetime] = UNSET
    r"""The date and time when the object was last updated."""

    created_at: OptionalNullable[datetime] = UNSET
    r"""The date and time when the object was created."""

    pass_through: Optional[List[PassThroughBody]] = None
    r"""The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "id",
            "subject",
            "type",
            "number_of_units",
            "number_of_media_files",
            "direction",
            "status",
            "scheduled_at",
            "sent_at",
            "webhook_url",
            "reference",
            "price",
            "error",
            "messaging_service_id",
            "custom_mappings",
            "updated_by",
            "created_by",
            "updated_at",
            "created_at",
            "pass_through",
        ]
        nullable_fields = [
            "custom_mappings",
            "updated_by",
            "created_by",
            "updated_at",
            "created_at",
        ]
        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


class MessageInputTypedDict(TypedDict):
    from_: str
    r"""The phone number that initiated the message."""
    to: str
    r"""The phone number that received the message."""
    body: str
    r"""The message text."""
    subject: NotRequired[str]
    type: NotRequired[MessageType]
    r"""Set to sms for SMS messages and mms for MMS messages."""
    scheduled_at: NotRequired[datetime]
    r"""The scheduled date and time of the message."""
    webhook_url: NotRequired[str]
    r"""Define a webhook to receive delivery notifications."""
    reference: NotRequired[str]
    r"""A client reference."""
    messaging_service_id: NotRequired[str]
    r"""The ID of the Messaging Service used with the message. In case of Plivo this links to the Powerpack ID."""
    pass_through: NotRequired[List[PassThroughBodyTypedDict]]
    r"""The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources."""


class MessageInput(BaseModel):
    from_: Annotated[str, pydantic.Field(alias="from")]
    r"""The phone number that initiated the message."""

    to: str
    r"""The phone number that received the message."""

    body: str
    r"""The message text."""

    subject: Optional[str] = None

    type: Optional[MessageType] = None
    r"""Set to sms for SMS messages and mms for MMS messages."""

    scheduled_at: Optional[datetime] = None
    r"""The scheduled date and time of the message."""

    webhook_url: Optional[str] = None
    r"""Define a webhook to receive delivery notifications."""

    reference: Optional[str] = None
    r"""A client reference."""

    messaging_service_id: Optional[str] = None
    r"""The ID of the Messaging Service used with the message. In case of Plivo this links to the Powerpack ID."""

    pass_through: Optional[List[PassThroughBody]] = None
    r"""The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources."""
