"""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, UNSET_SENTINEL
from documenso_sdk.utils import FieldMetadata, QueryParamMetadata
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 EnvelopeFindQueryParamType(str, Enum):
    r"""Filter envelopes by type (DOCUMENT or TEMPLATE)."""

    DOCUMENT = "DOCUMENT"
    TEMPLATE = "TEMPLATE"


class EnvelopeFindQueryParamSource(str, Enum):
    r"""Filter envelopes by how it was created."""

    DOCUMENT = "DOCUMENT"
    TEMPLATE = "TEMPLATE"
    TEMPLATE_DIRECT_LINK = "TEMPLATE_DIRECT_LINK"


class EnvelopeFindQueryParamStatus(str, Enum):
    r"""Filter envelopes by the current status."""

    DRAFT = "DRAFT"
    PENDING = "PENDING"
    COMPLETED = "COMPLETED"
    REJECTED = "REJECTED"


class EnvelopeFindOrderByColumn(str, Enum):
    CREATED_AT = "createdAt"


class EnvelopeFindOrderByDirection(str, Enum):
    r"""Sort direction."""

    ASC = "asc"
    DESC = "desc"


class EnvelopeFindRequestTypedDict(TypedDict):
    query: NotRequired[str]
    r"""The search query."""
    page: NotRequired[float]
    r"""The pagination page number, starts at 1."""
    per_page: NotRequired[float]
    r"""The number of items per page."""
    type: NotRequired[EnvelopeFindQueryParamType]
    r"""Filter envelopes by type (DOCUMENT or TEMPLATE)."""
    template_id: NotRequired[float]
    r"""Filter envelopes by the template ID used to create it."""
    source: NotRequired[EnvelopeFindQueryParamSource]
    r"""Filter envelopes by how it was created."""
    status: NotRequired[EnvelopeFindQueryParamStatus]
    r"""Filter envelopes by the current status."""
    folder_id: NotRequired[str]
    r"""Filter envelopes by folder ID."""
    order_by_column: NotRequired[EnvelopeFindOrderByColumn]
    order_by_direction: NotRequired[EnvelopeFindOrderByDirection]
    r"""Sort direction."""


class EnvelopeFindRequest(BaseModel):
    query: Annotated[
        Optional[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""The search query."""

    page: Annotated[
        Optional[float],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""The pagination page number, starts at 1."""

    per_page: Annotated[
        Optional[float],
        pydantic.Field(alias="perPage"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""The number of items per page."""

    type: Annotated[
        Optional[EnvelopeFindQueryParamType],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter envelopes by type (DOCUMENT or TEMPLATE)."""

    template_id: Annotated[
        Optional[float],
        pydantic.Field(alias="templateId"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter envelopes by the template ID used to create it."""

    source: Annotated[
        Optional[EnvelopeFindQueryParamSource],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter envelopes by how it was created."""

    status: Annotated[
        Optional[EnvelopeFindQueryParamStatus],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter envelopes by the current status."""

    folder_id: Annotated[
        Optional[str],
        pydantic.Field(alias="folderId"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Filter envelopes by folder ID."""

    order_by_column: Annotated[
        Optional[EnvelopeFindOrderByColumn],
        pydantic.Field(alias="orderByColumn"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None

    order_by_direction: Annotated[
        Optional[EnvelopeFindOrderByDirection],
        pydantic.Field(alias="orderByDirection"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = EnvelopeFindOrderByDirection.DESC
    r"""Sort direction."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "query",
                "page",
                "perPage",
                "type",
                "templateId",
                "source",
                "status",
                "folderId",
                "orderByColumn",
                "orderByDirection",
            ]
        )
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)

            if val != UNSET_SENTINEL:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m


class EnvelopeFindInternalServerErrorIssueTypedDict(TypedDict):
    message: str


class EnvelopeFindInternalServerErrorIssue(BaseModel):
    message: str


class EnvelopeFindInternalServerErrorData(BaseModel):
    message: str
    code: str
    issues: Optional[List[EnvelopeFindInternalServerErrorIssue]] = None


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

    data: EnvelopeFindInternalServerErrorData = field(hash=False)

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


class EnvelopeFindNotFoundIssue(BaseModel):
    message: str


class EnvelopeFindNotFoundErrorData(BaseModel):
    message: str
    code: str
    issues: Optional[List[EnvelopeFindNotFoundIssue]] = None


@dataclass(unsafe_hash=True)
class EnvelopeFindNotFoundError(DocumensoError):
    r"""Not found"""

    data: EnvelopeFindNotFoundErrorData = field(hash=False)

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


class EnvelopeFindForbiddenIssue(BaseModel):
    message: str


class EnvelopeFindForbiddenErrorData(BaseModel):
    message: str
    code: str
    issues: Optional[List[EnvelopeFindForbiddenIssue]] = None


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

    data: EnvelopeFindForbiddenErrorData = field(hash=False)

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


class EnvelopeFindUnauthorizedIssue(BaseModel):
    message: str


class EnvelopeFindUnauthorizedErrorData(BaseModel):
    message: str
    code: str
    issues: Optional[List[EnvelopeFindUnauthorizedIssue]] = None


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

    data: EnvelopeFindUnauthorizedErrorData = field(hash=False)

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


class EnvelopeFindBadRequestIssue(BaseModel):
    message: str


class EnvelopeFindBadRequestErrorData(BaseModel):
    message: str
    code: str
    issues: Optional[List[EnvelopeFindBadRequestIssue]] = None


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

    data: EnvelopeFindBadRequestErrorData = field(hash=False)

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


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


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


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


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


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


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


class EnvelopeFindAuthOptionsTypedDict(TypedDict):
    global_access_auth: List[EnvelopeFindGlobalAccessAuth]
    global_action_auth: List[EnvelopeFindGlobalActionAuth]


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

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


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


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


class EnvelopeFindUserTypedDict(TypedDict):
    id: float
    name: str
    email: str


class EnvelopeFindUser(BaseModel):
    id: float

    name: str

    email: str


class EnvelopeFindRole(str, Enum):
    CC = "CC"
    SIGNER = "SIGNER"
    VIEWER = "VIEWER"
    APPROVER = "APPROVER"
    ASSISTANT = "ASSISTANT"


class EnvelopeFindReadStatus(str, Enum):
    NOT_OPENED = "NOT_OPENED"
    OPENED = "OPENED"


class EnvelopeFindSigningStatus(str, Enum):
    NOT_SIGNED = "NOT_SIGNED"
    SIGNED = "SIGNED"
    REJECTED = "REJECTED"


class EnvelopeFindSendStatus(str, Enum):
    NOT_SENT = "NOT_SENT"
    SENT = "SENT"


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


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


class EnvelopeFindRecipientAuthOptionsTypedDict(TypedDict):
    access_auth: List[EnvelopeFindAccessAuth]
    action_auth: List[EnvelopeFindActionAuth]


class EnvelopeFindRecipientAuthOptions(BaseModel):
    access_auth: Annotated[
        List[EnvelopeFindAccessAuth], pydantic.Field(alias="accessAuth")
    ]

    action_auth: Annotated[
        List[EnvelopeFindActionAuth], pydantic.Field(alias="actionAuth")
    ]


class EnvelopeFindRecipientTypedDict(TypedDict):
    envelope_id: str
    role: EnvelopeFindRole
    read_status: EnvelopeFindReadStatus
    signing_status: EnvelopeFindSigningStatus
    send_status: EnvelopeFindSendStatus
    id: float
    email: str
    name: str
    token: str
    document_deleted_at: Nullable[str]
    expired: Nullable[str]
    signed_at: Nullable[str]
    auth_options: Nullable[EnvelopeFindRecipientAuthOptionsTypedDict]
    signing_order: Nullable[float]
    rejection_reason: Nullable[str]


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

    role: EnvelopeFindRole

    read_status: Annotated[EnvelopeFindReadStatus, pydantic.Field(alias="readStatus")]

    signing_status: Annotated[
        EnvelopeFindSigningStatus, pydantic.Field(alias="signingStatus")
    ]

    send_status: Annotated[EnvelopeFindSendStatus, pydantic.Field(alias="sendStatus")]

    id: float

    email: str

    name: str

    token: str

    document_deleted_at: Annotated[
        Nullable[str], pydantic.Field(alias="documentDeletedAt")
    ]

    expired: Nullable[str]

    signed_at: Annotated[Nullable[str], pydantic.Field(alias="signedAt")]

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

    signing_order: Annotated[Nullable[float], pydantic.Field(alias="signingOrder")]

    rejection_reason: Annotated[Nullable[str], pydantic.Field(alias="rejectionReason")]

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)

            if val != UNSET_SENTINEL:
                m[k] = val

        return m


class EnvelopeFindTeamTypedDict(TypedDict):
    id: float
    url: str


class EnvelopeFindTeam(BaseModel):
    id: float

    url: str


class EnvelopeFindDataTypedDict(TypedDict):
    internal_version: float
    type: EnvelopeFindDataType
    status: EnvelopeFindDataStatus
    source: EnvelopeFindDataSource
    visibility: EnvelopeFindVisibility
    template_type: EnvelopeFindTemplateType
    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[EnvelopeFindAuthOptionsTypedDict]
    form_values: Nullable[Dict[str, EnvelopeFindFormValuesTypedDict]]
    public_title: str
    public_description: str
    user_id: float
    team_id: float
    folder_id: Nullable[str]
    template_id: Nullable[float]
    user: EnvelopeFindUserTypedDict
    recipients: List[EnvelopeFindRecipientTypedDict]
    team: Nullable[EnvelopeFindTeamTypedDict]


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

    type: EnvelopeFindDataType

    status: EnvelopeFindDataStatus

    source: EnvelopeFindDataSource

    visibility: EnvelopeFindVisibility

    template_type: Annotated[
        EnvelopeFindTemplateType, 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[EnvelopeFindAuthOptions], pydantic.Field(alias="authOptions")
    ]

    form_values: Annotated[
        Nullable[Dict[str, EnvelopeFindFormValues]], 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")]

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

    user: EnvelopeFindUser

    recipients: List[EnvelopeFindRecipient]

    team: Nullable[EnvelopeFindTeam]

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)

            if val != UNSET_SENTINEL:
                m[k] = val

        return m


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

    data: List[EnvelopeFindDataTypedDict]
    count: float
    current_page: float
    per_page: float
    total_pages: float


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

    data: List[EnvelopeFindData]

    count: float

    current_page: Annotated[float, pydantic.Field(alias="currentPage")]

    per_page: Annotated[float, pydantic.Field(alias="perPage")]

    total_pages: Annotated[float, pydantic.Field(alias="totalPages")]
