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

from __future__ import annotations
from .messagetype import MessageType
from datetime import datetime
from gsmservice_gateway.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from gsmservice_gateway.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class MessageTypedDict(TypedDict):
    r"""An object defining the properties of a single message"""

    id: NotRequired[Nullable[int]]
    r"""Unique message identifier"""
    cid: NotRequired[Nullable[str]]
    r"""Custom message ID assigned by the User"""
    type: NotRequired[MessageType]
    r"""Message type (1 -> SMS PRO, 3 -> SMS ECO, 4 -> SMS 2WAY, 10 -> MMS)"""
    recipient: NotRequired[str]
    r"""A telephone number in international format (with a plus sign and the country code at the beginning, e.g. +48 for Poland)"""
    sender: NotRequired[Nullable[str]]
    r"""Message sender name"""
    parts: NotRequired[Nullable[int]]
    r"""The count of parts that message consists of"""
    sent_date: NotRequired[Nullable[datetime]]
    r"""Sending date and time (in ISO 8601 format)"""
    status_date: NotRequired[Nullable[datetime]]
    r"""Date and time of last status change (in ISO 8601 format)"""
    status_code: NotRequired[str]
    r"""Message status code"""
    status_description: NotRequired[str]
    r"""Human redable description of message status"""
    unicode: NotRequired[bool]
    r"""Did the message contain special characters, e.g. Polish diacritics?"""
    flash: NotRequired[bool]
    r"""Was the message sent with class 0 (FLASH)?"""
    price: NotRequired[float]
    r"""The price of message (in PLN)"""


class Message(BaseModel):
    r"""An object defining the properties of a single message"""

    id: OptionalNullable[int] = UNSET
    r"""Unique message identifier"""

    cid: OptionalNullable[str] = UNSET
    r"""Custom message ID assigned by the User"""

    type: Annotated[Optional[MessageType], PlainValidator(validate_open_enum(True))] = (
        None
    )
    r"""Message type (1 -> SMS PRO, 3 -> SMS ECO, 4 -> SMS 2WAY, 10 -> MMS)"""

    recipient: Optional[str] = None
    r"""A telephone number in international format (with a plus sign and the country code at the beginning, e.g. +48 for Poland)"""

    sender: OptionalNullable[str] = UNSET
    r"""Message sender name"""

    parts: OptionalNullable[int] = UNSET
    r"""The count of parts that message consists of"""

    sent_date: OptionalNullable[datetime] = UNSET
    r"""Sending date and time (in ISO 8601 format)"""

    status_date: OptionalNullable[datetime] = UNSET
    r"""Date and time of last status change (in ISO 8601 format)"""

    status_code: Optional[str] = None
    r"""Message status code"""

    status_description: Optional[str] = None
    r"""Human redable description of message status"""

    unicode: Optional[bool] = None
    r"""Did the message contain special characters, e.g. Polish diacritics?"""

    flash: Optional[bool] = None
    r"""Was the message sent with class 0 (FLASH)?"""

    price: Optional[float] = None
    r"""The price of message (in PLN)"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "id",
            "cid",
            "type",
            "recipient",
            "sender",
            "parts",
            "sent_date",
            "status_date",
            "status_code",
            "status_description",
            "unicode",
            "flash",
            "price",
        ]
        nullable_fields = ["id", "cid", "sender", "parts", "sent_date", "status_date"]
        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
