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

from __future__ import annotations
from documenso_sdk import utils
from documenso_sdk.types import BaseModel, Nullable, UNSET_SENTINEL
from documenso_sdk.utils import FieldMetadata, QueryParamMetadata
from enum import Enum
import pydantic
from pydantic import model_serializer
from typing import Dict, List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


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

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


class Status(str, Enum):
    r"""Filter documents by the current status"""

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


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


class OrderByDirection(str, Enum):
    ASC = "asc"
    DESC = "desc"


class DocumentFindDocumentsRequestTypedDict(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."""
    template_id: NotRequired[float]
    r"""Filter documents by the template ID used to create it."""
    source: NotRequired[Source]
    r"""Filter documents by how it was created."""
    status: NotRequired[Status]
    r"""Filter documents by the current status"""
    order_by_column: NotRequired[OrderByColumn]
    order_by_direction: NotRequired[OrderByDirection]


class DocumentFindDocumentsRequest(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."""

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

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

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

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

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


class DocumentFindDocumentsDocumentsIssuesTypedDict(TypedDict):
    message: str


class DocumentFindDocumentsDocumentsIssues(BaseModel):
    message: str


class DocumentFindDocumentsDocumentsResponse500ResponseBodyData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentFindDocumentsDocumentsIssues]] = None


class DocumentFindDocumentsDocumentsResponse500ResponseBody(Exception):
    r"""Internal server error"""

    data: DocumentFindDocumentsDocumentsResponse500ResponseBodyData

    def __init__(self, data: DocumentFindDocumentsDocumentsResponse500ResponseBodyData):
        self.data = data

    def __str__(self) -> str:
        return utils.marshal_json(
            self.data, DocumentFindDocumentsDocumentsResponse500ResponseBodyData
        )


class DocumentFindDocumentsIssuesTypedDict(TypedDict):
    message: str


class DocumentFindDocumentsIssues(BaseModel):
    message: str


class DocumentFindDocumentsDocumentsResponseResponseBodyData(BaseModel):
    message: str

    code: str

    issues: Optional[List[DocumentFindDocumentsIssues]] = None


class DocumentFindDocumentsDocumentsResponseResponseBody(Exception):
    r"""Not found"""

    data: DocumentFindDocumentsDocumentsResponseResponseBodyData

    def __init__(self, data: DocumentFindDocumentsDocumentsResponseResponseBodyData):
        self.data = data

    def __str__(self) -> str:
        return utils.marshal_json(
            self.data, DocumentFindDocumentsDocumentsResponseResponseBodyData
        )


class IssuesTypedDict(TypedDict):
    message: str


class Issues(BaseModel):
    message: str


class DocumentFindDocumentsDocumentsResponseBodyData(BaseModel):
    message: str

    code: str

    issues: Optional[List[Issues]] = None


class DocumentFindDocumentsDocumentsResponseBody(Exception):
    r"""Invalid input data"""

    data: DocumentFindDocumentsDocumentsResponseBodyData

    def __init__(self, data: DocumentFindDocumentsDocumentsResponseBodyData):
        self.data = data

    def __str__(self) -> str:
        return utils.marshal_json(
            self.data, DocumentFindDocumentsDocumentsResponseBodyData
        )


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


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


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


class DocumentFindDocumentsGlobalAccessAuth(str, Enum):
    r"""The type of authentication required for the recipient to access the document."""

    ACCOUNT = "ACCOUNT"


class DocumentFindDocumentsGlobalActionAuth(str, Enum):
    r"""The type of authentication required for the recipient to sign the document. This field is restricted to Enterprise plan users only."""

    ACCOUNT = "ACCOUNT"
    PASSKEY = "PASSKEY"
    TWO_FACTOR_AUTH = "TWO_FACTOR_AUTH"


class DocumentFindDocumentsAuthOptionsTypedDict(TypedDict):
    global_access_auth: Nullable[DocumentFindDocumentsGlobalAccessAuth]
    r"""The type of authentication required for the recipient to access the document."""
    global_action_auth: Nullable[DocumentFindDocumentsGlobalActionAuth]
    r"""The type of authentication required for the recipient to sign the document. This field is restricted to Enterprise plan users only."""


class DocumentFindDocumentsAuthOptions(BaseModel):
    global_access_auth: Annotated[
        Nullable[DocumentFindDocumentsGlobalAccessAuth],
        pydantic.Field(alias="globalAccessAuth"),
    ]
    r"""The type of authentication required for the recipient to access the document."""

    global_action_auth: Annotated[
        Nullable[DocumentFindDocumentsGlobalActionAuth],
        pydantic.Field(alias="globalActionAuth"),
    ]
    r"""The type of authentication required for the recipient to sign the document. This field is restricted to Enterprise plan users only."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = ["globalAccessAuth", "globalActionAuth"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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


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


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


class DocumentFindDocumentsUserTypedDict(TypedDict):
    id: int
    name: Nullable[str]
    email: str


class DocumentFindDocumentsUser(BaseModel):
    id: int

    name: Nullable[str]

    email: str

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = ["name"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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 DocumentFindDocumentsRole(str, Enum):
    CC = "CC"
    SIGNER = "SIGNER"
    VIEWER = "VIEWER"
    APPROVER = "APPROVER"


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


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


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


class DocumentFindDocumentsAccessAuth(str, Enum):
    r"""The type of authentication required for the recipient to access the document."""

    ACCOUNT = "ACCOUNT"


class DocumentFindDocumentsActionAuth(str, Enum):
    r"""The type of authentication required for the recipient to sign the document."""

    ACCOUNT = "ACCOUNT"
    PASSKEY = "PASSKEY"
    TWO_FACTOR_AUTH = "TWO_FACTOR_AUTH"
    EXPLICIT_NONE = "EXPLICIT_NONE"


class DocumentFindDocumentsDocumentsAuthOptionsTypedDict(TypedDict):
    access_auth: Nullable[DocumentFindDocumentsAccessAuth]
    r"""The type of authentication required for the recipient to access the document."""
    action_auth: Nullable[DocumentFindDocumentsActionAuth]
    r"""The type of authentication required for the recipient to sign the document."""


class DocumentFindDocumentsDocumentsAuthOptions(BaseModel):
    access_auth: Annotated[
        Nullable[DocumentFindDocumentsAccessAuth], pydantic.Field(alias="accessAuth")
    ]
    r"""The type of authentication required for the recipient to access the document."""

    action_auth: Annotated[
        Nullable[DocumentFindDocumentsActionAuth], pydantic.Field(alias="actionAuth")
    ]
    r"""The type of authentication required for the recipient to sign the document."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = ["accessAuth", "actionAuth"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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 DocumentFindDocumentsRecipientsTypedDict(TypedDict):
    role: DocumentFindDocumentsRole
    read_status: DocumentFindDocumentsReadStatus
    signing_status: DocumentFindDocumentsSigningStatus
    send_status: DocumentFindDocumentsSendStatus
    id: int
    document_id: Nullable[int]
    template_id: Nullable[int]
    email: str
    name: str
    token: str
    document_deleted_at: Nullable[str]
    expired: Nullable[str]
    signed_at: Nullable[str]
    auth_options: Nullable[DocumentFindDocumentsDocumentsAuthOptionsTypedDict]
    signing_order: Nullable[float]
    r"""The order in which the recipient should sign the document. Only works if the document is set to sequential signing."""
    rejection_reason: Nullable[str]


class DocumentFindDocumentsRecipients(BaseModel):
    role: DocumentFindDocumentsRole

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

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

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

    id: int

    document_id: Annotated[Nullable[int], pydantic.Field(alias="documentId")]

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

    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[DocumentFindDocumentsDocumentsAuthOptions],
        pydantic.Field(alias="authOptions"),
    ]

    signing_order: Annotated[Nullable[float], pydantic.Field(alias="signingOrder")]
    r"""The order in which the recipient should sign the document. Only works if the document is set to sequential signing."""

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

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = [
            "documentId",
            "templateId",
            "documentDeletedAt",
            "expired",
            "signedAt",
            "authOptions",
            "signingOrder",
            "rejectionReason",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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 TeamTypedDict(TypedDict):
    id: int
    url: str


class Team(BaseModel):
    id: int

    url: str


class DocumentFindDocumentsDataTypedDict(TypedDict):
    visibility: DocumentFindDocumentsVisibility
    status: DocumentFindDocumentsStatus
    source: DocumentFindDocumentsSource
    id: int
    external_id: Nullable[str]
    r"""A custom external ID you can use to identify the document."""
    user_id: float
    r"""The ID of the user that created this document."""
    auth_options: Nullable[DocumentFindDocumentsAuthOptionsTypedDict]
    form_values: Nullable[Dict[str, DocumentFindDocumentsFormValuesTypedDict]]
    title: str
    document_data_id: str
    created_at: str
    updated_at: str
    completed_at: Nullable[str]
    deleted_at: Nullable[str]
    team_id: Nullable[int]
    template_id: Nullable[int]
    user: DocumentFindDocumentsUserTypedDict
    recipients: List[DocumentFindDocumentsRecipientsTypedDict]
    team: Nullable[TeamTypedDict]


class DocumentFindDocumentsData(BaseModel):
    visibility: DocumentFindDocumentsVisibility

    status: DocumentFindDocumentsStatus

    source: DocumentFindDocumentsSource

    id: int

    external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]
    r"""A custom external ID you can use to identify the document."""

    user_id: Annotated[float, pydantic.Field(alias="userId")]
    r"""The ID of the user that created this document."""

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

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

    title: str

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

    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[Nullable[int], pydantic.Field(alias="teamId")]

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

    user: DocumentFindDocumentsUser

    recipients: List[DocumentFindDocumentsRecipients]

    team: Nullable[Team]

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = [
            "externalId",
            "authOptions",
            "formValues",
            "completedAt",
            "deletedAt",
            "teamId",
            "templateId",
            "team",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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 DocumentFindDocumentsResponseBodyTypedDict(TypedDict):
    r"""Successful response"""

    data: List[DocumentFindDocumentsDataTypedDict]
    count: float
    r"""The total number of items."""
    current_page: float
    r"""The current page number, starts at 1."""
    per_page: float
    r"""The number of items per page."""
    total_pages: float
    r"""The total number of pages."""


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

    data: List[DocumentFindDocumentsData]

    count: float
    r"""The total number of items."""

    current_page: Annotated[float, pydantic.Field(alias="currentPage")]
    r"""The current page number, starts at 1."""

    per_page: Annotated[float, pydantic.Field(alias="perPage")]
    r"""The number of items per page."""

    total_pages: Annotated[float, pydantic.Field(alias="totalPages")]
    r"""The total number of pages."""
