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

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


class PostV2MeetingsStart2TypedDict(TypedDict):
    date_: str
    r"""An ISO 8601 date indicating when an all day meeting starts."""


class PostV2MeetingsStart2(BaseModel):
    date_: Annotated[str, pydantic.Field(alias="date")]
    r"""An ISO 8601 date indicating when an all day meeting starts."""


class PostV2MeetingsStart1TypedDict(TypedDict):
    datetime_: datetime
    r"""An ISO 8601 datetime indicating when a non-all day meeting starts."""
    timezone: NotRequired[Nullable[str]]
    r"""The IANA timezone the meeting starts in. If a datetime value is provided without an offset, this timezone will be used to convert the datetime to UTC using the timezone offset. If a datetime value is provided with an offset, this timezone will not be used to apply any additional offset to the datetime. Invalid timezones will be treated as UTC."""


class PostV2MeetingsStart1(BaseModel):
    datetime_: Annotated[datetime, pydantic.Field(alias="datetime")]
    r"""An ISO 8601 datetime indicating when a non-all day meeting starts."""

    timezone: OptionalNullable[str] = UNSET
    r"""The IANA timezone the meeting starts in. If a datetime value is provided without an offset, this timezone will be used to convert the datetime to UTC using the timezone offset. If a datetime value is provided with an offset, this timezone will not be used to apply any additional offset to the datetime. Invalid timezones will be treated as UTC."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["timezone"])
        nullable_fields = set(["timezone"])
        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 PostV2MeetingsEnd2TypedDict(TypedDict):
    date_: str
    r"""An ISO 8601 date indicating when an all day meeting ends. Note that dates are exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one day meeting on June 3rd would end on June 4th, not June 3rd."""


class PostV2MeetingsEnd2(BaseModel):
    date_: Annotated[str, pydantic.Field(alias="date")]
    r"""An ISO 8601 date indicating when an all day meeting ends. Note that dates are exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one day meeting on June 3rd would end on June 4th, not June 3rd."""


class PostV2MeetingsEnd1TypedDict(TypedDict):
    datetime_: datetime
    r"""An ISO 8601 datetime indicating when a non-all day meeting ends. Note that this value is exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one hour meeting starting at 14:00 would end at 15:00, not 15:59:59."""
    timezone: NotRequired[Nullable[str]]
    r"""The IANA timezone the meeting ends in. If a datetime value is provided without an offset, this timezone will be used to convert the datetime to UTC using the timezone offset. If a datetime value is provided with an offset, this timezone will not be used to apply any additional offset to the datetime. Invalid timezones will be treated as UTC."""


class PostV2MeetingsEnd1(BaseModel):
    datetime_: Annotated[datetime, pydantic.Field(alias="datetime")]
    r"""An ISO 8601 datetime indicating when a non-all day meeting ends. Note that this value is exclusive, meaning that the meeting ends before the specified time, not at it. For example, a one hour meeting starting at 14:00 would end at 15:00, not 15:59:59."""

    timezone: OptionalNullable[str] = UNSET
    r"""The IANA timezone the meeting ends in. If a datetime value is provided without an offset, this timezone will be used to convert the datetime to UTC using the timezone offset. If a datetime value is provided with an offset, this timezone will not be used to apply any additional offset to the datetime. Invalid timezones will be treated as UTC."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["timezone"])
        nullable_fields = set(["timezone"])
        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


PostV2MeetingsStartUnionTypedDict = TypeAliasType(
    "PostV2MeetingsStartUnionTypedDict",
    Union[PostV2MeetingsStart2TypedDict, PostV2MeetingsStart1TypedDict],
)
r"""When the meeting starts. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""


PostV2MeetingsStartUnion = TypeAliasType(
    "PostV2MeetingsStartUnion", Union[PostV2MeetingsStart2, PostV2MeetingsStart1]
)
r"""When the meeting starts. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""


PostV2MeetingsEndUnionTypedDict = TypeAliasType(
    "PostV2MeetingsEndUnionTypedDict",
    Union[PostV2MeetingsEnd2TypedDict, PostV2MeetingsEnd1TypedDict],
)
r"""When the meeting ends. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""


PostV2MeetingsEndUnion = TypeAliasType(
    "PostV2MeetingsEndUnion", Union[PostV2MeetingsEnd2, PostV2MeetingsEnd1]
)
r"""When the meeting ends. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""


IsOrganizerFalse = Literal["false",]


IsOrganizerTrue = Literal["true",]


IsOrganizerTypedDict = TypeAliasType(
    "IsOrganizerTypedDict", Union[bool, IsOrganizerTrue, IsOrganizerFalse]
)
r"""Whether or not the participant is the organizer of the meeting."""


IsOrganizer = TypeAliasType(
    "IsOrganizer", Union[bool, IsOrganizerTrue, IsOrganizerFalse]
)
r"""Whether or not the participant is the organizer of the meeting."""


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


class PostV2MeetingsParticipantTypedDict(TypedDict):
    email_address: str
    r"""The email address of the participant. New person records and companies will automatically be created based upon the email address values provided."""
    is_organizer: IsOrganizerTypedDict
    r"""Whether or not the participant is the organizer of the meeting."""
    status: PostV2MeetingsStatus
    r"""The status of the individual meeting participant."""


class PostV2MeetingsParticipant(BaseModel):
    email_address: str
    r"""The email address of the participant. New person records and companies will automatically be created based upon the email address values provided."""

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

    status: PostV2MeetingsStatus
    r"""The status of the individual meeting participant."""


class PostV2MeetingsLinkedRecordTypedDict(TypedDict):
    object: str
    r"""The slug or UUID of the object that the record being linked belongs to."""
    record_id: str
    r"""The UUID of the record being linked."""


class PostV2MeetingsLinkedRecord(BaseModel):
    object: str
    r"""The slug or UUID of the object that the record being linked belongs to."""

    record_id: str
    r"""The UUID of the record being linked."""


Provider = Literal[
    "google",
    "microsoft",
]
r"""The email provider used to sync the meeting."""


class ExternalRefTypedDict(TypedDict):
    ical_uid: str
    r"""The ical uid of the meeting."""
    provider: Provider
    r"""The email provider used to sync the meeting."""
    is_recurring: bool
    r"""Whether or not the meeting is recurring."""
    original_start_time: NotRequired[str]
    r"""The original start time of the meeting. Use a timestamp with a specified offset for all day and non-all day meetings. This property is required for recurring event exceptions and optional otherwise."""


class ExternalRef(BaseModel):
    ical_uid: str
    r"""The ical uid of the meeting."""

    provider: Provider
    r"""The email provider used to sync the meeting."""

    is_recurring: bool
    r"""Whether or not the meeting is recurring."""

    original_start_time: Optional[str] = None
    r"""The original start time of the meeting. Use a timestamp with a specified offset for all day and non-all day meetings. This property is required for recurring event exceptions and optional otherwise."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["original_start_time"])
        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:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m


ExternalRefUnionTypedDict = TypeAliasType(
    "ExternalRefUnionTypedDict", Union[ExternalRefTypedDict, str]
)
r"""A consistent external reference used to match and de-duplicate meetings. Can be either a plain string (for external system IDs) or an object with `ical_uid` and `provider`. If you are writing data into Attio which is based upon calendar events that you have synced from a Google or Microsoft calendar, you must use the iCal format to avoid creating duplicate meetings inside Attio."""


ExternalRefUnion = TypeAliasType("ExternalRefUnion", Union[ExternalRef, str])
r"""A consistent external reference used to match and de-duplicate meetings. Can be either a plain string (for external system IDs) or an object with `ical_uid` and `provider`. If you are writing data into Attio which is based upon calendar events that you have synced from a Google or Microsoft calendar, you must use the iCal format to avoid creating duplicate meetings inside Attio."""


class PostV2MeetingsDataTypedDict(TypedDict):
    title: str
    r"""The title of the meeting."""
    description: str
    r"""The description of the meeting."""
    start: PostV2MeetingsStartUnionTypedDict
    r"""When the meeting starts. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""
    end: PostV2MeetingsEndUnionTypedDict
    r"""When the meeting ends. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""
    is_all_day: bool
    r"""Whether or not the meeting is an all day event. All day events may span multiple days. When true, start and end must use date format. When false, start and end must use datetime with timezone format."""
    participants: List[PostV2MeetingsParticipantTypedDict]
    external_ref: ExternalRefUnionTypedDict
    r"""A consistent external reference used to match and de-duplicate meetings. Can be either a plain string (for external system IDs) or an object with `ical_uid` and `provider`. If you are writing data into Attio which is based upon calendar events that you have synced from a Google or Microsoft calendar, you must use the iCal format to avoid creating duplicate meetings inside Attio."""
    linked_records: NotRequired[List[PostV2MeetingsLinkedRecordTypedDict]]
    r"""A list of records to link to the meeting. Each record is specified by its object (slug or UUID) and record ID (UUID). Attio will automatically link the meeting participants' companies to the meeting; this behavior is asynchronous."""


class PostV2MeetingsData(BaseModel):
    title: str
    r"""The title of the meeting."""

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

    start: PostV2MeetingsStartUnion
    r"""When the meeting starts. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""

    end: PostV2MeetingsEndUnion
    r"""When the meeting ends. Use a datetime and optional timezone for non-all day meetings, or a date for all day meetings."""

    is_all_day: bool
    r"""Whether or not the meeting is an all day event. All day events may span multiple days. When true, start and end must use date format. When false, start and end must use datetime with timezone format."""

    participants: List[PostV2MeetingsParticipant]

    external_ref: ExternalRefUnion
    r"""A consistent external reference used to match and de-duplicate meetings. Can be either a plain string (for external system IDs) or an object with `ical_uid` and `provider`. If you are writing data into Attio which is based upon calendar events that you have synced from a Google or Microsoft calendar, you must use the iCal format to avoid creating duplicate meetings inside Attio."""

    linked_records: Optional[List[PostV2MeetingsLinkedRecord]] = None
    r"""A list of records to link to the meeting. Each record is specified by its object (slug or UUID) and record ID (UUID). Attio will automatically link the meeting participants' companies to the meeting; this behavior is asynchronous."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["linked_records"])
        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:
                if val is not None or k not in optional_fields:
                    m[k] = val

        return m


class PostV2MeetingsRequestTypedDict(TypedDict):
    data: PostV2MeetingsDataTypedDict


class PostV2MeetingsRequest(BaseModel):
    data: PostV2MeetingsData


PostV2MeetingsType = Literal["invalid_request_error",]


PostV2MeetingsCode = Literal["validation_type",]


class PostV2MeetingsResponseTypedDict(TypedDict):
    r"""Success"""

    data: MeetingTypedDict


class PostV2MeetingsResponse(BaseModel):
    r"""Success"""

    data: Meeting


try:
    PostV2MeetingsStart2.model_rebuild()
except NameError:
    pass
try:
    PostV2MeetingsStart1.model_rebuild()
except NameError:
    pass
try:
    PostV2MeetingsEnd2.model_rebuild()
except NameError:
    pass
try:
    PostV2MeetingsEnd1.model_rebuild()
except NameError:
    pass
