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

from __future__ import annotations
from dataclasses import dataclass, field
from documenso_sdk.models import DocumensoError
from documenso_sdk.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from enum import Enum
import httpx
import pydantic
from pydantic import model_serializer
from typing import Dict, List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


class DocumentDistributeDateFormat(str, Enum):
    YYYY_M_MDD_HH_MM_A = "yyyy-MM-dd hh:mm a"
    YYYY_M_MDD = "yyyy-MM-dd"
    DD_MM_SLASH_YYYY = "dd/MM/yyyy"
    MM_DD_SLASH_YYYY = "MM/dd/yyyy"
    YY_M_MDD = "yy-MM-dd"
    MMMM_DD_COMMA_YYYY = "MMMM dd, yyyy"
    EEEE_MMMM_DD_COMMA_YYYY = "EEEE, MMMM dd, yyyy"
    DD_MM_SLASH_YYYY_HH_MM_A = "dd/MM/yyyy hh:mm a"
    DD_MM_SLASH_YYYY_H_HMM = "dd/MM/yyyy HH:mm"
    MM_DD_SLASH_YYYY_HH_MM_A = "MM/dd/yyyy hh:mm a"
    MM_DD_SLASH_YYYY_H_HMM = "MM/dd/yyyy HH:mm"
    DD_DOT_MM_DOT_YYYY = "dd.MM.yyyy"
    DD_DOT_MM_DOT_YYYY_H_HMM = "dd.MM.yyyy HH:mm"
    YYYY_M_MDD_H_HMM = "yyyy-MM-dd HH:mm"
    YY_M_MDD_HH_MM_A = "yy-MM-dd hh:mm a"
    YY_M_MDD_H_HMM = "yy-MM-dd HH:mm"
    YYYY_M_MDD_H_HMMSS = "yyyy-MM-dd HH:mm:ss"
    MMMM_DD_COMMA_YYYY_HH_MM_A = "MMMM dd, yyyy hh:mm a"
    MMMM_DD_COMMA_YYYY_H_HMM = "MMMM dd, yyyy HH:mm"
    EEEE_MMMM_DD_COMMA_YYYY_HH_MM_A = "EEEE, MMMM dd, yyyy hh:mm a"
    EEEE_MMMM_DD_COMMA_YYYY_H_HMM = "EEEE, MMMM dd, yyyy HH:mm"
    ISO8601_FULL = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"


class DocumentDistributeDistributionMethod(str, Enum):
    EMAIL = "EMAIL"
    NONE = "NONE"


class DocumentDistributeLanguage(str, Enum):
    DE = "de"
    EN = "en"
    FR = "fr"
    ES = "es"
    IT = "it"
    PL = "pl"


class DocumentDistributeEmailSettingsTypedDict(TypedDict):
    recipient_signing_request: NotRequired[bool]
    recipient_removed: NotRequired[bool]
    recipient_signed: NotRequired[bool]
    document_pending: NotRequired[bool]
    document_completed: NotRequired[bool]
    document_deleted: NotRequired[bool]
    owner_document_completed: NotRequired[bool]


class DocumentDistributeEmailSettings(BaseModel):
    recipient_signing_request: Annotated[
        Optional[bool], pydantic.Field(alias="recipientSigningRequest")
    ] = True

    recipient_removed: Annotated[
        Optional[bool], pydantic.Field(alias="recipientRemoved")
    ] = True

    recipient_signed: Annotated[
        Optional[bool], pydantic.Field(alias="recipientSigned")
    ] = True

    document_pending: Annotated[
        Optional[bool], pydantic.Field(alias="documentPending")
    ] = True

    document_completed: Annotated[
        Optional[bool], pydantic.Field(alias="documentCompleted")
    ] = True

    document_deleted: Annotated[
        Optional[bool], pydantic.Field(alias="documentDeleted")
    ] = True

    owner_document_completed: Annotated[
        Optional[bool], pydantic.Field(alias="ownerDocumentCompleted")
    ] = True


class DocumentDistributeMetaTypedDict(TypedDict):
    subject: NotRequired[str]
    message: NotRequired[str]
    timezone: NotRequired[str]
    date_format: NotRequired[DocumentDistributeDateFormat]
    distribution_method: NotRequired[DocumentDistributeDistributionMethod]
    redirect_url: NotRequired[str]
    language: NotRequired[DocumentDistributeLanguage]
    email_id: NotRequired[Nullable[str]]
    email_reply_to: NotRequired[Nullable[str]]
    email_settings: NotRequired[DocumentDistributeEmailSettingsTypedDict]


class DocumentDistributeMeta(BaseModel):
    subject: Optional[str] = None

    message: Optional[str] = None

    timezone: Optional[str] = None

    date_format: Annotated[
        Optional[DocumentDistributeDateFormat], pydantic.Field(alias="dateFormat")
    ] = None

    distribution_method: Annotated[
        Optional[DocumentDistributeDistributionMethod],
        pydantic.Field(alias="distributionMethod"),
    ] = None

    redirect_url: Annotated[Optional[str], pydantic.Field(alias="redirectUrl")] = None

    language: Optional[DocumentDistributeLanguage] = None

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

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

    email_settings: Annotated[
        Optional[DocumentDistributeEmailSettings], pydantic.Field(alias="emailSettings")
    ] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "subject",
            "message",
            "timezone",
            "dateFormat",
            "distributionMethod",
            "redirectUrl",
            "language",
            "emailId",
            "emailReplyTo",
            "emailSettings",
        ]
        nullable_fields = ["emailId", "emailReplyTo"]
        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 DocumentDistributeRequestTypedDict(TypedDict):
    document_id: float
    meta: NotRequired[DocumentDistributeMetaTypedDict]


class DocumentDistributeRequest(BaseModel):
    document_id: Annotated[float, pydantic.Field(alias="documentId")]

    meta: Optional[DocumentDistributeMeta] = None


class DocumentDistributeInternalServerErrorIssueTypedDict(TypedDict):
    message: str


class DocumentDistributeInternalServerErrorIssue(BaseModel):
    message: str


class DocumentDistributeInternalServerErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentDistributeInternalServerErrorIssue]] = None


@dataclass(unsafe_hash=True)
class DocumentDistributeInternalServerError(DocumensoError):
    r"""Internal server error"""

    data: DocumentDistributeInternalServerErrorData = field(hash=False)

    def __init__(
        self,
        data: DocumentDistributeInternalServerErrorData,
        raw_response: httpx.Response,
        body: Optional[str] = None,
    ):
        fallback = body or raw_response.text
        message = str(data.message) or fallback
        super().__init__(message, raw_response, body)
        object.__setattr__(self, "data", data)


class DocumentDistributeForbiddenIssueTypedDict(TypedDict):
    message: str


class DocumentDistributeForbiddenIssue(BaseModel):
    message: str


class DocumentDistributeForbiddenErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentDistributeForbiddenIssue]] = None


@dataclass(unsafe_hash=True)
class DocumentDistributeForbiddenError(DocumensoError):
    r"""Insufficient access"""

    data: DocumentDistributeForbiddenErrorData = field(hash=False)

    def __init__(
        self,
        data: DocumentDistributeForbiddenErrorData,
        raw_response: httpx.Response,
        body: Optional[str] = None,
    ):
        fallback = body or raw_response.text
        message = str(data.message) or fallback
        super().__init__(message, raw_response, body)
        object.__setattr__(self, "data", data)


class DocumentDistributeUnauthorizedIssueTypedDict(TypedDict):
    message: str


class DocumentDistributeUnauthorizedIssue(BaseModel):
    message: str


class DocumentDistributeUnauthorizedErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentDistributeUnauthorizedIssue]] = None


@dataclass(unsafe_hash=True)
class DocumentDistributeUnauthorizedError(DocumensoError):
    r"""Authorization not provided"""

    data: DocumentDistributeUnauthorizedErrorData = field(hash=False)

    def __init__(
        self,
        data: DocumentDistributeUnauthorizedErrorData,
        raw_response: httpx.Response,
        body: Optional[str] = None,
    ):
        fallback = body or raw_response.text
        message = str(data.message) or fallback
        super().__init__(message, raw_response, body)
        object.__setattr__(self, "data", data)


class DocumentDistributeBadRequestIssueTypedDict(TypedDict):
    message: str


class DocumentDistributeBadRequestIssue(BaseModel):
    message: str


class DocumentDistributeBadRequestErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentDistributeBadRequestIssue]] = None


@dataclass(unsafe_hash=True)
class DocumentDistributeBadRequestError(DocumensoError):
    r"""Invalid input data"""

    data: DocumentDistributeBadRequestErrorData = field(hash=False)

    def __init__(
        self,
        data: DocumentDistributeBadRequestErrorData,
        raw_response: httpx.Response,
        body: Optional[str] = None,
    ):
        fallback = body or raw_response.text
        message = str(data.message) or fallback
        super().__init__(message, raw_response, body)
        object.__setattr__(self, "data", data)


class DocumentDistributeVisibility(str, Enum):
    EVERYONE = "EVERYONE"
    MANAGER_AND_ABOVE = "MANAGER_AND_ABOVE"
    ADMIN = "ADMIN"


class DocumentDistributeStatus(str, Enum):
    DRAFT = "DRAFT"
    PENDING = "PENDING"
    COMPLETED = "COMPLETED"
    REJECTED = "REJECTED"


class DocumentDistributeSource(str, Enum):
    DOCUMENT = "DOCUMENT"
    TEMPLATE = "TEMPLATE"
    TEMPLATE_DIRECT_LINK = "TEMPLATE_DIRECT_LINK"


class DocumentDistributeGlobalAccessAuth(str, Enum):
    ACCOUNT = "ACCOUNT"
    TWO_FACTOR_AUTH = "TWO_FACTOR_AUTH"


class DocumentDistributeGlobalActionAuth(str, Enum):
    ACCOUNT = "ACCOUNT"
    PASSKEY = "PASSKEY"
    TWO_FACTOR_AUTH = "TWO_FACTOR_AUTH"
    PASSWORD = "PASSWORD"


class DocumentDistributeAuthOptionsTypedDict(TypedDict):
    global_access_auth: List[DocumentDistributeGlobalAccessAuth]
    global_action_auth: List[DocumentDistributeGlobalActionAuth]


class DocumentDistributeAuthOptions(BaseModel):
    global_access_auth: Annotated[
        List[DocumentDistributeGlobalAccessAuth],
        pydantic.Field(alias="globalAccessAuth"),
    ]

    global_action_auth: Annotated[
        List[DocumentDistributeGlobalActionAuth],
        pydantic.Field(alias="globalActionAuth"),
    ]


DocumentDistributeFormValuesTypedDict = TypeAliasType(
    "DocumentDistributeFormValuesTypedDict", Union[str, bool, float]
)


DocumentDistributeFormValues = TypeAliasType(
    "DocumentDistributeFormValues", Union[str, bool, float]
)


class DocumentDistributeResponseTypedDict(TypedDict):
    r"""Successful response"""

    visibility: DocumentDistributeVisibility
    status: DocumentDistributeStatus
    source: DocumentDistributeSource
    id: float
    external_id: Nullable[str]
    user_id: float
    auth_options: Nullable[DocumentDistributeAuthOptionsTypedDict]
    form_values: Nullable[Dict[str, DocumentDistributeFormValuesTypedDict]]
    title: str
    created_at: str
    updated_at: str
    completed_at: Nullable[str]
    deleted_at: Nullable[str]
    team_id: float
    folder_id: Nullable[str]
    use_legacy_field_insertion: bool
    envelope_id: str
    internal_version: float
    document_data_id: NotRequired[str]
    template_id: NotRequired[Nullable[float]]


class DocumentDistributeResponse(BaseModel):
    r"""Successful response"""

    visibility: DocumentDistributeVisibility

    status: DocumentDistributeStatus

    source: DocumentDistributeSource

    id: float

    external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]

    user_id: Annotated[float, pydantic.Field(alias="userId")]

    auth_options: Annotated[
        Nullable[DocumentDistributeAuthOptions], pydantic.Field(alias="authOptions")
    ]

    form_values: Annotated[
        Nullable[Dict[str, DocumentDistributeFormValues]],
        pydantic.Field(alias="formValues"),
    ]

    title: str

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

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

    completed_at: Annotated[Nullable[str], pydantic.Field(alias="completedAt")]

    deleted_at: Annotated[Nullable[str], pydantic.Field(alias="deletedAt")]

    team_id: Annotated[float, pydantic.Field(alias="teamId")]

    folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]

    use_legacy_field_insertion: Annotated[
        bool, pydantic.Field(alias="useLegacyFieldInsertion")
    ]

    envelope_id: Annotated[str, pydantic.Field(alias="envelopeId")]

    internal_version: Annotated[float, pydantic.Field(alias="internalVersion")]

    document_data_id: Annotated[
        Optional[str], pydantic.Field(alias="documentDataId")
    ] = ""

    template_id: Annotated[
        OptionalNullable[float], pydantic.Field(alias="templateId")
    ] = UNSET

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["documentDataId", "templateId"]
        nullable_fields = [
            "externalId",
            "authOptions",
            "formValues",
            "completedAt",
            "deletedAt",
            "folderId",
            "templateId",
        ]
        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
