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

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


class MeetingIDTypedDict(TypedDict):
    workspace_id: str
    r"""The ID of the workspace the meeting belongs to."""
    meeting_id: str
    r"""The ID of the Attio meeting."""


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

    meeting_id: str
    r"""The ID of the Attio meeting."""


class Start2TypedDict(TypedDict):
    date_: str
    r"""If an all day event, a date representing when the meeting starts."""


class Start2(BaseModel):
    date_: Annotated[str, pydantic.Field(alias="date")]
    r"""If an all day event, a date representing when the meeting starts."""


class Start1TypedDict(TypedDict):
    datetime_: str
    r"""If a non-all day event, a datetime representing when the meeting starts. Datetimes are formatted as UTC if no timezone is available. If a timezone is available, the datetime will offset using the specified timezone."""
    timezone: Nullable[str]
    r"""The IANA timezone in which the meeting starts, if available."""


class Start1(BaseModel):
    datetime_: Annotated[str, pydantic.Field(alias="datetime")]
    r"""If a non-all day event, a datetime representing when the meeting starts. Datetimes are formatted as UTC if no timezone is available. If a timezone is available, the datetime will offset using the specified timezone."""

    timezone: Nullable[str]
    r"""The IANA timezone in which the meeting starts, if available."""

    @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


class End2TypedDict(TypedDict):
    date_: str
    r"""If an all day event, a date representing when the meeting ends."""


class End2(BaseModel):
    date_: Annotated[str, pydantic.Field(alias="date")]
    r"""If an all day event, a date representing when the meeting ends."""


class End1TypedDict(TypedDict):
    datetime_: str
    r"""A datetime representing when the meeting ends. All day meetings will return a date whereas non-all day meetings will return a datetime. Datetimes do not include timezone information; please refer to `timezone` for timezone information. Following iCalendar RFC 5545, the `end_at` property is exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one day meeting on June 3rd would have an `end_at` of June 4th, not June 3rd; a one hour meeting starting at 14:00 would have an `end_at` of 15:00, not 14:00."""
    timezone: Nullable[str]
    r"""The IANA timezone in which the meeting ends, if available."""


class End1(BaseModel):
    datetime_: Annotated[str, pydantic.Field(alias="datetime")]
    r"""A datetime representing when the meeting ends. All day meetings will return a date whereas non-all day meetings will return a datetime. Datetimes do not include timezone information; please refer to `timezone` for timezone information. Following iCalendar RFC 5545, the `end_at` property is exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one day meeting on June 3rd would have an `end_at` of June 4th, not June 3rd; a one hour meeting starting at 14:00 would have an `end_at` of 15:00, not 14:00."""

    timezone: Nullable[str]
    r"""The IANA timezone in which the meeting ends, if available."""

    @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


StartUnionTypedDict = TypeAliasType(
    "StartUnionTypedDict", Union[Start2TypedDict, Start1TypedDict]
)


StartUnion = TypeAliasType("StartUnion", Union[Start2, Start1])


EndUnionTypedDict = TypeAliasType(
    "EndUnionTypedDict", Union[End2TypedDict, End1TypedDict]
)


EndUnion = TypeAliasType("EndUnion", Union[End2, End1])


MeetingStatus = Literal[
    "accepted",
    "tentative",
    "declined",
    "pending",
]
r"""The status of the individual meeting participant."""


class ParticipantTypedDict(TypedDict):
    status: MeetingStatus
    r"""The status of the individual meeting participant."""
    is_organizer: bool
    r"""Whether or not the participant is the organizer of the meeting."""
    email_address: Nullable[str]
    r"""The normalized email address of the meeting participant."""


class Participant(BaseModel):
    status: MeetingStatus
    r"""The status of the individual meeting participant."""

    is_organizer: bool
    r"""Whether or not the participant is the organizer of the meeting."""

    email_address: Nullable[str]
    r"""The normalized email address of the meeting participant."""

    @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


class MeetingLinkedRecordTypedDict(TypedDict):
    object_slug: str
    r"""The slug of the object the meeting linked record belongs to."""
    object_id: str
    r"""The ID of the object the meeting linked record belongs to."""
    record_id: str
    r"""The ID of the meeting linked record."""


class MeetingLinkedRecord(BaseModel):
    object_slug: str
    r"""The slug of the object the meeting linked record belongs to."""

    object_id: str
    r"""The ID of the object the meeting linked record belongs to."""

    record_id: str
    r"""The ID of the meeting linked record."""


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


class MeetingCreatedByActorTypedDict(TypedDict):
    r"""The actor that created this meeting."""

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


class MeetingCreatedByActor(BaseModel):
    r"""The actor that created this meeting."""

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

    type: OptionalNullable[MeetingType] = 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 MeetingTypedDict(TypedDict):
    id: MeetingIDTypedDict
    title: str
    r"""The title of the meeting."""
    description: str
    r"""The description of the meeting."""
    is_all_day: bool
    r"""Whether or not the meeting is an all day event. All day events may span multiple days."""
    start: StartUnionTypedDict
    end: EndUnionTypedDict
    participants: List[ParticipantTypedDict]
    linked_records: List[MeetingLinkedRecordTypedDict]
    r"""A list of records that are linked to the meeting. Participants with matching person records are automatically linked to the meeting but other records may also be linked explicitly."""
    created_at: str
    r"""Timestamp representing when the meeting was created."""
    created_by_actor: MeetingCreatedByActorTypedDict
    r"""The actor that created this meeting."""


class Meeting(BaseModel):
    id: MeetingID

    title: str
    r"""The title of the meeting."""

    description: str
    r"""The description of the meeting."""

    is_all_day: bool
    r"""Whether or not the meeting is an all day event. All day events may span multiple days."""

    start: StartUnion

    end: EndUnion

    participants: List[Participant]

    linked_records: List[MeetingLinkedRecord]
    r"""A list of records that are linked to the meeting. Participants with matching person records are automatically linked to the meeting but other records may also be linked explicitly."""

    created_at: str
    r"""Timestamp representing when the meeting was created."""

    created_by_actor: MeetingCreatedByActor
    r"""The actor that created this meeting."""


try:
    Start2.model_rebuild()
except NameError:
    pass
try:
    Start1.model_rebuild()
except NameError:
    pass
try:
    End2.model_rebuild()
except NameError:
    pass
try:
    End1.model_rebuild()
except NameError:
    pass
