"""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 documenso_sdk.utils import FieldMetadata, MultipartFormMetadata
from enum import Enum
import httpx
import io
import pydantic
from pydantic import model_serializer
from typing import IO, List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict


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


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


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


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


class TemplateCreateTemplateDateFormat(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 TemplateCreateTemplateDistributionMethod(str, Enum):
    EMAIL = "EMAIL"
    NONE = "NONE"


class TemplateCreateTemplateEmailSettingsTypedDict(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 TemplateCreateTemplateEmailSettings(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 TemplateCreateTemplateLanguage(str, Enum):
    DE = "de"
    EN = "en"
    FR = "fr"
    ES = "es"
    IT = "it"
    PL = "pl"


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


class TemplateCreateTemplateMetaTypedDict(TypedDict):
    subject: NotRequired[str]
    message: NotRequired[str]
    timezone: NotRequired[str]
    date_format: NotRequired[TemplateCreateTemplateDateFormat]
    distribution_method: NotRequired[TemplateCreateTemplateDistributionMethod]
    email_id: NotRequired[Nullable[str]]
    email_reply_to: NotRequired[Nullable[str]]
    email_settings: NotRequired[TemplateCreateTemplateEmailSettingsTypedDict]
    redirect_url: NotRequired[str]
    language: NotRequired[TemplateCreateTemplateLanguage]
    typed_signature_enabled: NotRequired[bool]
    upload_signature_enabled: NotRequired[bool]
    draw_signature_enabled: NotRequired[bool]
    signing_order: NotRequired[TemplateCreateTemplateSigningOrder]
    allow_dictate_next_signer: NotRequired[bool]


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

    message: Optional[str] = None

    timezone: Optional[str] = None

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

    distribution_method: Annotated[
        Optional[TemplateCreateTemplateDistributionMethod],
        pydantic.Field(alias="distributionMethod"),
    ] = 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[TemplateCreateTemplateEmailSettings],
        pydantic.Field(alias="emailSettings"),
    ] = None

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

    language: Optional[TemplateCreateTemplateLanguage] = 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

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

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

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "subject",
            "message",
            "timezone",
            "dateFormat",
            "distributionMethod",
            "emailId",
            "emailReplyTo",
            "emailSettings",
            "redirectUrl",
            "language",
            "typedSignatureEnabled",
            "uploadSignatureEnabled",
            "drawSignatureEnabled",
            "signingOrder",
            "allowDictateNextSigner",
        ]
        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 TemplateCreateTemplateTypeLink(str, Enum):
    LINK = "link"


class TemplateCreateTemplateAttachmentTypedDict(TypedDict):
    label: str
    data: str
    type: NotRequired[TemplateCreateTemplateTypeLink]


class TemplateCreateTemplateAttachment(BaseModel):
    label: str

    data: str

    type: Optional[TemplateCreateTemplateTypeLink] = TemplateCreateTemplateTypeLink.LINK


class TemplateCreateTemplatePayloadTypedDict(TypedDict):
    title: str
    folder_id: NotRequired[str]
    external_id: NotRequired[Nullable[str]]
    visibility: NotRequired[TemplateCreateTemplateVisibility]
    global_access_auth: NotRequired[List[TemplateCreateTemplateGlobalAccessAuth]]
    global_action_auth: NotRequired[List[TemplateCreateTemplateGlobalActionAuth]]
    public_title: NotRequired[str]
    public_description: NotRequired[str]
    type: NotRequired[TemplateCreateTemplateType]
    meta: NotRequired[TemplateCreateTemplateMetaTypedDict]
    attachments: NotRequired[List[TemplateCreateTemplateAttachmentTypedDict]]


class TemplateCreateTemplatePayload(BaseModel):
    title: str

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

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

    visibility: Optional[TemplateCreateTemplateVisibility] = None

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

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

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

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

    type: Optional[TemplateCreateTemplateType] = None

    meta: Optional[TemplateCreateTemplateMeta] = None

    attachments: Optional[List[TemplateCreateTemplateAttachment]] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "folderId",
            "externalId",
            "visibility",
            "globalAccessAuth",
            "globalActionAuth",
            "publicTitle",
            "publicDescription",
            "type",
            "meta",
            "attachments",
        ]
        nullable_fields = ["externalId"]
        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 TemplateCreateTemplateFileTypedDict(TypedDict):
    file_name: str
    content: Union[bytes, IO[bytes], io.BufferedReader]
    content_type: NotRequired[str]


class TemplateCreateTemplateFile(BaseModel):
    file_name: Annotated[
        str, pydantic.Field(alias="fileName"), FieldMetadata(multipart=True)
    ]

    content: Annotated[
        Union[bytes, IO[bytes], io.BufferedReader],
        pydantic.Field(alias=""),
        FieldMetadata(multipart=MultipartFormMetadata(content=True)),
    ]

    content_type: Annotated[
        Optional[str],
        pydantic.Field(alias="Content-Type"),
        FieldMetadata(multipart=True),
    ] = None


class TemplateCreateTemplateRequestTypedDict(TypedDict):
    payload: TemplateCreateTemplatePayloadTypedDict
    file: TemplateCreateTemplateFileTypedDict


class TemplateCreateTemplateRequest(BaseModel):
    payload: Annotated[
        TemplateCreateTemplatePayload,
        FieldMetadata(multipart=MultipartFormMetadata(json=True)),
    ]

    file: Annotated[
        TemplateCreateTemplateFile,
        FieldMetadata(multipart=MultipartFormMetadata(file=True)),
    ]


class TemplateCreateTemplateInternalServerErrorIssueTypedDict(TypedDict):
    message: str


class TemplateCreateTemplateInternalServerErrorIssue(BaseModel):
    message: str


class TemplateCreateTemplateInternalServerErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[TemplateCreateTemplateInternalServerErrorIssue]] = None


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

    data: TemplateCreateTemplateInternalServerErrorData = field(hash=False)

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


class TemplateCreateTemplateForbiddenIssue(BaseModel):
    message: str


class TemplateCreateTemplateForbiddenErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[TemplateCreateTemplateForbiddenIssue]] = None


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

    data: TemplateCreateTemplateForbiddenErrorData = field(hash=False)

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


class TemplateCreateTemplateUnauthorizedIssue(BaseModel):
    message: str


class TemplateCreateTemplateUnauthorizedErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[TemplateCreateTemplateUnauthorizedIssue]] = None


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

    data: TemplateCreateTemplateUnauthorizedErrorData = field(hash=False)

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


class TemplateCreateTemplateBadRequestIssue(BaseModel):
    message: str


class TemplateCreateTemplateBadRequestErrorData(BaseModel):
    message: str

    code: str

    issues: Optional[List[TemplateCreateTemplateBadRequestIssue]] = None


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

    data: TemplateCreateTemplateBadRequestErrorData = field(hash=False)

    def __init__(
        self,
        data: TemplateCreateTemplateBadRequestErrorData,
        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 TemplateCreateTemplateResponseTypedDict(TypedDict):
    r"""Successful response"""

    envelope_id: str
    id: float


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

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

    id: float
