"""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 EnvelopeUpdateDataVisibility(str, Enum):
    EVERYONE = "EVERYONE"
    MANAGER_AND_ABOVE = "MANAGER_AND_ABOVE"
    ADMIN = "ADMIN"


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


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


class EnvelopeUpdateDataTypedDict(TypedDict):
    title: NotRequired[str]
    external_id: NotRequired[Nullable[str]]
    visibility: NotRequired[EnvelopeUpdateDataVisibility]
    global_access_auth: NotRequired[List[EnvelopeUpdateDataGlobalAccessAuth]]
    global_action_auth: NotRequired[List[EnvelopeUpdateDataGlobalActionAuth]]
    folder_id: NotRequired[Nullable[str]]


class EnvelopeUpdateData(BaseModel):
    title: Optional[str] = None

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

    visibility: Optional[EnvelopeUpdateDataVisibility] = None

    global_access_auth: Annotated[
        Optional[List[EnvelopeUpdateDataGlobalAccessAuth]],
        pydantic.Field(alias="globalAccessAuth"),
    ] = None

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

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

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "title",
            "externalId",
            "visibility",
            "globalAccessAuth",
            "globalActionAuth",
            "folderId",
        ]
        nullable_fields = ["externalId", "folderId"]
        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 EnvelopeUpdateDateFormat(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 EnvelopeUpdateDistributionMethod(str, Enum):
    EMAIL = "EMAIL"
    NONE = "NONE"


class EnvelopeUpdateSigningOrder(str, Enum):
    PARALLEL = "PARALLEL"
    SEQUENTIAL = "SEQUENTIAL"


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


class EnvelopeUpdateEmailSettingsTypedDict(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 EnvelopeUpdateEmailSettings(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 EnvelopeUpdateMetaTypedDict(TypedDict):
    subject: NotRequired[str]
    message: NotRequired[str]
    timezone: NotRequired[str]
    date_format: NotRequired[EnvelopeUpdateDateFormat]
    distribution_method: NotRequired[EnvelopeUpdateDistributionMethod]
    signing_order: NotRequired[EnvelopeUpdateSigningOrder]
    allow_dictate_next_signer: NotRequired[bool]
    redirect_url: NotRequired[str]
    language: NotRequired[EnvelopeUpdateLanguage]
    typed_signature_enabled: NotRequired[bool]
    upload_signature_enabled: NotRequired[bool]
    draw_signature_enabled: NotRequired[bool]
    email_id: NotRequired[Nullable[str]]
    email_reply_to: NotRequired[Nullable[str]]
    email_settings: NotRequired[Nullable[EnvelopeUpdateEmailSettingsTypedDict]]


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

    message: Optional[str] = None

    timezone: Optional[str] = None

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

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

    signing_order: Annotated[
        Optional[EnvelopeUpdateSigningOrder], pydantic.Field(alias="signingOrder")
    ] = None

    allow_dictate_next_signer: Annotated[
        Optional[bool], pydantic.Field(alias="allowDictateNextSigner")
    ] = None

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

    language: Optional[EnvelopeUpdateLanguage] = None

    typed_signature_enabled: Annotated[
        Optional[bool], pydantic.Field(alias="typedSignatureEnabled")
    ] = None

    upload_signature_enabled: Annotated[
        Optional[bool], pydantic.Field(alias="uploadSignatureEnabled")
    ] = None

    draw_signature_enabled: Annotated[
        Optional[bool], pydantic.Field(alias="drawSignatureEnabled")
    ] = 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[
        OptionalNullable[EnvelopeUpdateEmailSettings],
        pydantic.Field(alias="emailSettings"),
    ] = UNSET

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "subject",
            "message",
            "timezone",
            "dateFormat",
            "distributionMethod",
            "signingOrder",
            "allowDictateNextSigner",
            "redirectUrl",
            "language",
            "typedSignatureEnabled",
            "uploadSignatureEnabled",
            "drawSignatureEnabled",
            "emailId",
            "emailReplyTo",
            "emailSettings",
        ]
        nullable_fields = ["emailId", "emailReplyTo", "emailSettings"]
        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 EnvelopeUpdateRequestTypedDict(TypedDict):
    envelope_id: str
    data: NotRequired[EnvelopeUpdateDataTypedDict]
    meta: NotRequired[EnvelopeUpdateMetaTypedDict]


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

    data: Optional[EnvelopeUpdateData] = None

    meta: Optional[EnvelopeUpdateMeta] = None


class EnvelopeUpdateInternalServerErrorIssueTypedDict(TypedDict):
    message: str


class EnvelopeUpdateInternalServerErrorIssue(BaseModel):
    message: str


class EnvelopeUpdateInternalServerErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[EnvelopeUpdateInternalServerErrorIssue]] = None


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

    data: EnvelopeUpdateInternalServerErrorData = field(hash=False)

    def __init__(
        self,
        data: EnvelopeUpdateInternalServerErrorData,
        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 EnvelopeUpdateForbiddenIssueTypedDict(TypedDict):
    message: str


class EnvelopeUpdateForbiddenIssue(BaseModel):
    message: str


class EnvelopeUpdateForbiddenErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[EnvelopeUpdateForbiddenIssue]] = None


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

    data: EnvelopeUpdateForbiddenErrorData = field(hash=False)

    def __init__(
        self,
        data: EnvelopeUpdateForbiddenErrorData,
        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 EnvelopeUpdateUnauthorizedIssueTypedDict(TypedDict):
    message: str


class EnvelopeUpdateUnauthorizedIssue(BaseModel):
    message: str


class EnvelopeUpdateUnauthorizedErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[EnvelopeUpdateUnauthorizedIssue]] = None


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

    data: EnvelopeUpdateUnauthorizedErrorData = field(hash=False)

    def __init__(
        self,
        data: EnvelopeUpdateUnauthorizedErrorData,
        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 EnvelopeUpdateBadRequestIssueTypedDict(TypedDict):
    message: str


class EnvelopeUpdateBadRequestIssue(BaseModel):
    message: str


class EnvelopeUpdateBadRequestErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[EnvelopeUpdateBadRequestIssue]] = None


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

    data: EnvelopeUpdateBadRequestErrorData = field(hash=False)

    def __init__(
        self,
        data: EnvelopeUpdateBadRequestErrorData,
        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 EnvelopeUpdateType(str, Enum):
    DOCUMENT = "DOCUMENT"
    TEMPLATE = "TEMPLATE"


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


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


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


class EnvelopeUpdateTemplateType(str, Enum):
    PUBLIC = "PUBLIC"
    PRIVATE = "PRIVATE"


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


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


class EnvelopeUpdateAuthOptionsTypedDict(TypedDict):
    global_access_auth: List[EnvelopeUpdateGlobalAccessAuthResponse]
    global_action_auth: List[EnvelopeUpdateGlobalActionAuthResponse]


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

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


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


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


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

    internal_version: float
    type: EnvelopeUpdateType
    status: EnvelopeUpdateStatus
    source: EnvelopeUpdateSource
    visibility: EnvelopeUpdateVisibilityResponse
    template_type: EnvelopeUpdateTemplateType
    id: str
    secondary_id: str
    external_id: Nullable[str]
    created_at: str
    updated_at: str
    completed_at: Nullable[str]
    deleted_at: Nullable[str]
    title: str
    auth_options: Nullable[EnvelopeUpdateAuthOptionsTypedDict]
    form_values: Nullable[Dict[str, EnvelopeUpdateFormValuesTypedDict]]
    public_title: str
    public_description: str
    user_id: float
    team_id: float
    folder_id: Nullable[str]


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

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

    type: EnvelopeUpdateType

    status: EnvelopeUpdateStatus

    source: EnvelopeUpdateSource

    visibility: EnvelopeUpdateVisibilityResponse

    template_type: Annotated[
        EnvelopeUpdateTemplateType, pydantic.Field(alias="templateType")
    ]

    id: str

    secondary_id: Annotated[str, pydantic.Field(alias="secondaryId")]

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

    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")]

    title: str

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

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

    public_title: Annotated[str, pydantic.Field(alias="publicTitle")]

    public_description: Annotated[str, pydantic.Field(alias="publicDescription")]

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

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

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

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