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

from __future__ import annotations
from attio.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from attio.utils import get_discriminator
import pydantic
from pydantic import Discriminator, model_serializer
from typing import List, Literal, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


class NoteIDTypedDict(TypedDict):
    workspace_id: str
    r"""The ID of the workspace the note belongs to."""
    note_id: str
    r"""The ID of the note."""


class NoteID(BaseModel):
    workspace_id: str
    r"""The ID of the workspace the note belongs to."""

    note_id: str
    r"""The ID of the note."""


TypeRecord = Literal["record",]
r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""


class TagRecordTypedDict(TypedDict):
    type: TypeRecord
    r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""
    object: str
    r"""The slug or ID of the object that the tagged record belongs to."""
    record_id: str
    r"""The ID of the record that is tagged in the note."""


class TagRecord(BaseModel):
    type: TypeRecord
    r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""

    object: str
    r"""The slug or ID of the object that the tagged record belongs to."""

    record_id: str
    r"""The ID of the record that is tagged in the note."""


TagTypeWorkspaceMember = Literal["workspace-member",]
r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""


class TagWorkspaceMemberTypedDict(TypedDict):
    type: TagTypeWorkspaceMember
    r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""
    workspace_member_id: str
    r"""The ID of the workspace member that is tagged in the note."""


class TagWorkspaceMember(BaseModel):
    type: TagTypeWorkspaceMember
    r"""The type of entity tagged in the note. Can be either 'workspace-member' or 'record'"""

    workspace_member_id: str
    r"""The ID of the workspace member that is tagged in the note."""


TagTypedDict = TypeAliasType(
    "TagTypedDict", Union[TagWorkspaceMemberTypedDict, TagRecordTypedDict]
)


Tag = Annotated[
    Union[
        Annotated[TagWorkspaceMember, pydantic.Tag("workspace-member")],
        Annotated[TagRecord, pydantic.Tag("record")],
    ],
    Discriminator(lambda m: get_discriminator(m, "type", "type")),
]


NoteCreatedByActorType = Literal[
    "api-token",
    "workspace-member",
    "system",
    "app",
]
r"""The type of actor. [Read more information on actor types here](/docs/actors)."""


class NoteCreatedByActorTypedDict(TypedDict):
    r"""The actor that created this note."""

    id: NotRequired[Nullable[str]]
    r"""An ID to identify the actor."""
    type: NotRequired[Nullable[NoteCreatedByActorType]]
    r"""The type of actor. [Read more information on actor types here](/docs/actors)."""


class NoteCreatedByActor(BaseModel):
    r"""The actor that created this note."""

    id: OptionalNullable[str] = UNSET
    r"""An ID to identify the actor."""

    type: OptionalNullable[NoteCreatedByActorType] = UNSET
    r"""The type of actor. [Read more information on actor types here](/docs/actors)."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["id", "type"])
        nullable_fields = set(["id", "type"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

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

        return m


class NoteTypedDict(TypedDict):
    id: NoteIDTypedDict
    parent_object: str
    r"""The slug or ID of the parent object the note belongs to."""
    parent_record_id: str
    r"""The ID of the parent record the note belongs to."""
    title: str
    r"""The note title. The title is plaintext only and has no formatting."""
    meeting_id: Nullable[str]
    r"""The ID of the meeting associated with this note, or null if no meeting is associated."""
    content_plaintext: str
    r"""The plaintext representation of the note content. The line feed character `\n` represents new lines within the note content."""
    content_markdown: str
    r"""The markdown representation of the note content. Supports a subset of markdown features including:
    - Headings (levels 1-3 only with `#`, `##`, `###`)
    - Unordered lists (`-`, `*`, `+`)
    - Ordered lists (`1.`, `2.`, etc.)
    - Text styling: `**bold**`, `*italic*`, `~~strikethrough~~`, `==highlighted==`
    - Links: `[link text](https://example.com)`

    Note that note images are not returned as part of the markdown API representation.
    """
    tags: List[TagTypedDict]
    r"""An array of records or workspace members that are @-tagged in the note content."""
    created_by_actor: NoteCreatedByActorTypedDict
    r"""The actor that created this note."""
    created_at: str
    r"""When the note was created."""


class Note(BaseModel):
    id: NoteID

    parent_object: str
    r"""The slug or ID of the parent object the note belongs to."""

    parent_record_id: str
    r"""The ID of the parent record the note belongs to."""

    title: str
    r"""The note title. The title is plaintext only and has no formatting."""

    meeting_id: Nullable[str]
    r"""The ID of the meeting associated with this note, or null if no meeting is associated."""

    content_plaintext: str
    r"""The plaintext representation of the note content. The line feed character `\n` represents new lines within the note content."""

    content_markdown: str
    r"""The markdown representation of the note content. Supports a subset of markdown features including:
    - Headings (levels 1-3 only with `#`, `##`, `###`)
    - Unordered lists (`-`, `*`, `+`)
    - Ordered lists (`1.`, `2.`, etc.)
    - Text styling: `**bold**`, `*italic*`, `~~strikethrough~~`, `==highlighted==`
    - Links: `[link text](https://example.com)`

    Note that note images are not returned as part of the markdown API representation.
    """

    tags: List[Tag]
    r"""An array of records or workspace members that are @-tagged in the note content."""

    created_by_actor: NoteCreatedByActor
    r"""The actor that created this note."""

    created_at: str
    r"""When the note was created."""

    @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, serialized.get(n))

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

        return m
