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

from __future__ import annotations
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from enum import Enum
import pydantic
from pydantic import model_serializer
from typing import Any, Dict, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class Mode(str, Enum):
    r"""The mode to use for tracking the lead event. `async` will not block the request; `wait` will block the request until the lead event is fully recorded in Dub; `deferred` will defer the lead event creation to a subsequent request."""

    ASYNC = "async"
    WAIT = "wait"
    DEFERRED = "deferred"


class TrackLeadRequestBodyTypedDict(TypedDict):
    click_id: str
    r"""The unique ID of the click that the lead conversion event is attributed to. You can read this value from `dub_id` cookie. [For deferred lead tracking]: If an empty string is provided, Dub will try to find an existing customer with the provided `customerExternalId` and use the `clickId` from the customer if found."""
    event_name: str
    r"""The name of the lead event to track. Can also be used as a unique identifier to associate a given lead event for a customer for a subsequent sale event (via the `leadEventName` prop in `/track/sale`)."""
    customer_external_id: str
    r"""The unique ID of the customer in your system. Will be used to identify and attribute all future events to this customer."""
    customer_name: NotRequired[Nullable[str]]
    r"""The name of the customer. If not passed, a random name will be generated (e.g. “Big Red Caribou”)."""
    customer_email: NotRequired[Nullable[str]]
    r"""The email address of the customer."""
    customer_avatar: NotRequired[Nullable[str]]
    r"""The avatar URL of the customer."""
    mode: NotRequired[Mode]
    r"""The mode to use for tracking the lead event. `async` will not block the request; `wait` will block the request until the lead event is fully recorded in Dub; `deferred` will defer the lead event creation to a subsequent request."""
    event_quantity: NotRequired[Nullable[float]]
    r"""The numerical value associated with this lead event (e.g., number of provisioned seats in a free trial). If defined as N, the lead event will be tracked N times."""
    metadata: NotRequired[Nullable[Dict[str, Any]]]
    r"""Additional metadata to be stored with the lead event. Max 10,000 characters."""


class TrackLeadRequestBody(BaseModel):
    click_id: Annotated[str, pydantic.Field(alias="clickId")]
    r"""The unique ID of the click that the lead conversion event is attributed to. You can read this value from `dub_id` cookie. [For deferred lead tracking]: If an empty string is provided, Dub will try to find an existing customer with the provided `customerExternalId` and use the `clickId` from the customer if found."""

    event_name: Annotated[str, pydantic.Field(alias="eventName")]
    r"""The name of the lead event to track. Can also be used as a unique identifier to associate a given lead event for a customer for a subsequent sale event (via the `leadEventName` prop in `/track/sale`)."""

    customer_external_id: Annotated[str, pydantic.Field(alias="customerExternalId")]
    r"""The unique ID of the customer in your system. Will be used to identify and attribute all future events to this customer."""

    customer_name: Annotated[
        OptionalNullable[str], pydantic.Field(alias="customerName")
    ] = None
    r"""The name of the customer. If not passed, a random name will be generated (e.g. “Big Red Caribou”)."""

    customer_email: Annotated[
        OptionalNullable[str], pydantic.Field(alias="customerEmail")
    ] = None
    r"""The email address of the customer."""

    customer_avatar: Annotated[
        OptionalNullable[str], pydantic.Field(alias="customerAvatar")
    ] = None
    r"""The avatar URL of the customer."""

    mode: Optional[Mode] = Mode.ASYNC
    r"""The mode to use for tracking the lead event. `async` will not block the request; `wait` will block the request until the lead event is fully recorded in Dub; `deferred` will defer the lead event creation to a subsequent request."""

    event_quantity: Annotated[
        OptionalNullable[float], pydantic.Field(alias="eventQuantity")
    ] = UNSET
    r"""The numerical value associated with this lead event (e.g., number of provisioned seats in a free trial). If defined as N, the lead event will be tracked N times."""

    metadata: OptionalNullable[Dict[str, Any]] = UNSET
    r"""Additional metadata to be stored with the lead event. Max 10,000 characters."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "customerName",
                "customerEmail",
                "customerAvatar",
                "mode",
                "eventQuantity",
                "metadata",
            ]
        )
        nullable_fields = set(
            [
                "customerName",
                "customerEmail",
                "customerAvatar",
                "eventQuantity",
                "metadata",
            ]
        )
        null_default_fields = set(["customerName", "customerEmail", "customerAvatar"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (
                    self.__pydantic_fields_set__.intersection({n})
                    or k in null_default_fields
                )  # 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 ClickTypedDict(TypedDict):
    id: str


class Click(BaseModel):
    id: str


class LinkTypedDict(TypedDict):
    id: str
    r"""The unique ID of the short link."""
    domain: str
    r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
    key: str
    r"""The short link slug. If not provided, a random 7-character slug will be generated."""
    short_link: str
    r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
    url: str
    r"""The destination URL of the short link."""
    partner_id: Nullable[str]
    r"""The ID of the partner the short link is associated with."""
    program_id: Nullable[str]
    r"""The ID of the program the short link is associated with."""
    tenant_id: Nullable[str]
    r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
    external_id: Nullable[str]
    r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""


class Link(BaseModel):
    id: str
    r"""The unique ID of the short link."""

    domain: str
    r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""

    key: str
    r"""The short link slug. If not provided, a random 7-character slug will be generated."""

    short_link: Annotated[str, pydantic.Field(alias="shortLink")]
    r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""

    url: str
    r"""The destination URL of the short link."""

    partner_id: Annotated[Nullable[str], pydantic.Field(alias="partnerId")]
    r"""The ID of the partner the short link is associated with."""

    program_id: Annotated[Nullable[str], pydantic.Field(alias="programId")]
    r"""The ID of the program the short link is associated with."""

    tenant_id: Annotated[Nullable[str], pydantic.Field(alias="tenantId")]
    r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""

    external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]
    r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""

    @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 CustomerTypedDict(TypedDict):
    name: Nullable[str]
    email: Nullable[str]
    avatar: Nullable[str]
    external_id: Nullable[str]


class Customer(BaseModel):
    name: Nullable[str]

    email: Nullable[str]

    avatar: Nullable[str]

    external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]

    @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 TrackLeadResponseBodyTypedDict(TypedDict):
    r"""A lead was tracked."""

    click: ClickTypedDict
    link: Nullable[LinkTypedDict]
    customer: CustomerTypedDict


class TrackLeadResponseBody(BaseModel):
    r"""A lead was tracked."""

    click: Click

    link: Nullable[Link]

    customer: Customer

    @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
