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

from __future__ import annotations
from .attribute import Attribute, AttributeTypedDict
from .input_value_union import InputValueUnion, InputValueUnionTypedDict
from attio.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from attio.utils import (
    FieldMetadata,
    PathParamMetadata,
    RequestMetadata,
    get_discriminator,
)
from pydantic import Discriminator, Tag, model_serializer
from typing import Any, List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


PatchV2TargetIdentifierAttributesAttributeTarget = Literal[
    "objects",
    "lists",
]
r"""Whether the attribute is on an object or a list."""


PatchV2TargetIdentifierAttributesAttributeTypeStatic = Literal["static",]


class PatchV2TargetIdentifierAttributesAttributeDefaultValueStaticTypedDict(TypedDict):
    type: PatchV2TargetIdentifierAttributesAttributeTypeStatic
    template: List[InputValueUnionTypedDict]


class PatchV2TargetIdentifierAttributesAttributeDefaultValueStatic(BaseModel):
    type: PatchV2TargetIdentifierAttributesAttributeTypeStatic

    template: List[InputValueUnion]


PatchV2TargetIdentifierAttributesAttributeTypeDynamic = Literal["dynamic",]


PatchV2TargetIdentifierAttributesAttributeTemplate = Literal["current-user",]
r"""For actor reference attributes, you may pass a dynamic value of `\"current-user\"`. When creating new records or entries, this will cause the actor reference value to be populated with either the workspace member or API token that created the record/entry."""


class PatchV2TargetIdentifierAttributesAttributeDefaultValueDynamicTypedDict(TypedDict):
    type: PatchV2TargetIdentifierAttributesAttributeTypeDynamic
    template: Any


class PatchV2TargetIdentifierAttributesAttributeDefaultValueDynamic(BaseModel):
    type: PatchV2TargetIdentifierAttributesAttributeTypeDynamic

    template: Any


PatchV2TargetIdentifierAttributesAttributeDefaultValueUnionTypedDict = TypeAliasType(
    "PatchV2TargetIdentifierAttributesAttributeDefaultValueUnionTypedDict",
    Union[
        PatchV2TargetIdentifierAttributesAttributeDefaultValueDynamicTypedDict,
        PatchV2TargetIdentifierAttributesAttributeDefaultValueStaticTypedDict,
    ],
)
r"""The default value for this attribute. Static values are used to directly populate values using their contents. Dynamic values are used to lookup data at the point of creation. For example, you could use a dynamic value to insert a value for the currently logged in user. Which default values are available is dependent on the type of the attribute. Default values are not currently supported on people or company objects."""


PatchV2TargetIdentifierAttributesAttributeDefaultValueUnion = Annotated[
    Union[
        Annotated[
            PatchV2TargetIdentifierAttributesAttributeDefaultValueDynamic,
            Tag("dynamic"),
        ],
        Annotated[
            PatchV2TargetIdentifierAttributesAttributeDefaultValueStatic, Tag("static")
        ],
    ],
    Discriminator(lambda m: get_discriminator(m, "type", "type")),
]
r"""The default value for this attribute. Static values are used to directly populate values using their contents. Dynamic values are used to lookup data at the point of creation. For example, you could use a dynamic value to insert a value for the currently logged in user. Which default values are available is dependent on the type of the attribute. Default values are not currently supported on people or company objects."""


PatchV2TargetIdentifierAttributesAttributeDefaultCurrencyCode = Literal[
    "ARS",
    "AUD",
    "BRL",
    "BGN",
    "CAD",
    "CLP",
    "CNY",
    "COP",
    "CZK",
    "DKK",
    "EUR",
    "FJD",
    "HKD",
    "HUF",
    "ISK",
    "INR",
    "ILS",
    "JPY",
    "KES",
    "KRW",
    "MYR",
    "MXN",
    "NTD",
    "NZD",
    "NGN",
    "NOK",
    "XPF",
    "PEN",
    "PHP",
    "PLN",
    "GBP",
    "RWF",
    "SAR",
    "SGD",
    "ZAR",
    "SEK",
    "CHF",
    "THB",
    "AED",
    "UYU",
    "USD",
]
r"""The ISO4217 code representing the currency that values for this attribute should be stored in."""


PatchV2TargetIdentifierAttributesAttributeDisplayType = Literal[
    "code",
    "name",
    "narrowSymbol",
    "symbol",
]
r"""How the currency should be displayed across the app. \"code\" will display the ISO currency code e.g. \"USD\", \"name\" will display the localized currency name e.g. \"British pound\", \"narrowSymbol\" will display \"$1\" instead of \"US$1\" and \"symbol\" will display a localized currency symbol such as \"$\"."""


class PatchV2TargetIdentifierAttributesAttributeCurrencyTypedDict(TypedDict):
    r"""Configuration available for attributes of type \"currency\"."""

    default_currency_code: PatchV2TargetIdentifierAttributesAttributeDefaultCurrencyCode
    r"""The ISO4217 code representing the currency that values for this attribute should be stored in."""
    display_type: PatchV2TargetIdentifierAttributesAttributeDisplayType
    r"""How the currency should be displayed across the app. \"code\" will display the ISO currency code e.g. \"USD\", \"name\" will display the localized currency name e.g. \"British pound\", \"narrowSymbol\" will display \"$1\" instead of \"US$1\" and \"symbol\" will display a localized currency symbol such as \"$\"."""


class PatchV2TargetIdentifierAttributesAttributeCurrency(BaseModel):
    r"""Configuration available for attributes of type \"currency\"."""

    default_currency_code: PatchV2TargetIdentifierAttributesAttributeDefaultCurrencyCode
    r"""The ISO4217 code representing the currency that values for this attribute should be stored in."""

    display_type: PatchV2TargetIdentifierAttributesAttributeDisplayType
    r"""How the currency should be displayed across the app. \"code\" will display the ISO currency code e.g. \"USD\", \"name\" will display the localized currency name e.g. \"British pound\", \"narrowSymbol\" will display \"$1\" instead of \"US$1\" and \"symbol\" will display a localized currency symbol such as \"$\"."""


class PatchV2TargetIdentifierAttributesAttributeRecordReferenceTypedDict(TypedDict):
    r"""Configuration available for attributes of type \"record-reference\"."""

    allowed_objects: List[str]
    r"""A list of slugs or UUIDs to indicate which objects records are allowed to belong to. If `relationship` is also provided, this must contain only the relationship object."""


class PatchV2TargetIdentifierAttributesAttributeRecordReference(BaseModel):
    r"""Configuration available for attributes of type \"record-reference\"."""

    allowed_objects: List[str]
    r"""A list of slugs or UUIDs to indicate which objects records are allowed to belong to. If `relationship` is also provided, this must contain only the relationship object."""


class PatchV2TargetIdentifierAttributesAttributeConfigTypedDict(TypedDict):
    r"""Additional, type-dependent configuration for the attribute."""

    currency: NotRequired[PatchV2TargetIdentifierAttributesAttributeCurrencyTypedDict]
    r"""Configuration available for attributes of type \"currency\"."""
    record_reference: NotRequired[
        PatchV2TargetIdentifierAttributesAttributeRecordReferenceTypedDict
    ]
    r"""Configuration available for attributes of type \"record-reference\"."""


class PatchV2TargetIdentifierAttributesAttributeConfig(BaseModel):
    r"""Additional, type-dependent configuration for the attribute."""

    currency: Optional[PatchV2TargetIdentifierAttributesAttributeCurrency] = None
    r"""Configuration available for attributes of type \"currency\"."""

    record_reference: Optional[
        PatchV2TargetIdentifierAttributesAttributeRecordReference
    ] = None
    r"""Configuration available for attributes of type \"record-reference\"."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["currency", "record_reference"])
        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 PatchV2TargetIdentifierAttributesAttributeDataTypedDict(TypedDict):
    title: NotRequired[str]
    r"""The name of the attribute. The title will be visible across Attio's UI."""
    description: NotRequired[Nullable[str]]
    r"""A text description for the attribute."""
    api_slug: NotRequired[str]
    r"""A unique, human-readable slug to access the attribute through URLs and API calls. Formatted in snake case."""
    is_required: NotRequired[bool]
    r"""When `is_required` is `true`, new records/entries must have a value for this attribute. If `false`, values may be `null`. This value does not affect existing data and you do not need to backfill `null` values if changing `is_required` from `false` to `true`."""
    is_unique: NotRequired[bool]
    r"""Whether or not new values for this attribute must be unique. Uniqueness restrictions are only applied to new data and do not apply retroactively to previously created data."""
    default_value: NotRequired[
        Nullable[PatchV2TargetIdentifierAttributesAttributeDefaultValueUnionTypedDict]
    ]
    r"""The default value for this attribute. Static values are used to directly populate values using their contents. Dynamic values are used to lookup data at the point of creation. For example, you could use a dynamic value to insert a value for the currently logged in user. Which default values are available is dependent on the type of the attribute. Default values are not currently supported on people or company objects."""
    config: NotRequired[PatchV2TargetIdentifierAttributesAttributeConfigTypedDict]
    r"""Additional, type-dependent configuration for the attribute."""
    is_archived: NotRequired[bool]
    r"""Whether the attribute has been archived or not. See our [archiving guide](/docs/archiving-vs-deleting) for more information on archiving."""


class PatchV2TargetIdentifierAttributesAttributeData(BaseModel):
    title: Optional[str] = None
    r"""The name of the attribute. The title will be visible across Attio's UI."""

    description: OptionalNullable[str] = UNSET
    r"""A text description for the attribute."""

    api_slug: Optional[str] = None
    r"""A unique, human-readable slug to access the attribute through URLs and API calls. Formatted in snake case."""

    is_required: Optional[bool] = None
    r"""When `is_required` is `true`, new records/entries must have a value for this attribute. If `false`, values may be `null`. This value does not affect existing data and you do not need to backfill `null` values if changing `is_required` from `false` to `true`."""

    is_unique: Optional[bool] = None
    r"""Whether or not new values for this attribute must be unique. Uniqueness restrictions are only applied to new data and do not apply retroactively to previously created data."""

    default_value: OptionalNullable[
        PatchV2TargetIdentifierAttributesAttributeDefaultValueUnion
    ] = UNSET
    r"""The default value for this attribute. Static values are used to directly populate values using their contents. Dynamic values are used to lookup data at the point of creation. For example, you could use a dynamic value to insert a value for the currently logged in user. Which default values are available is dependent on the type of the attribute. Default values are not currently supported on people or company objects."""

    config: Optional[PatchV2TargetIdentifierAttributesAttributeConfig] = None
    r"""Additional, type-dependent configuration for the attribute."""

    is_archived: Optional[bool] = None
    r"""Whether the attribute has been archived or not. See our [archiving guide](/docs/archiving-vs-deleting) for more information on archiving."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "title",
                "description",
                "api_slug",
                "is_required",
                "is_unique",
                "default_value",
                "config",
                "is_archived",
            ]
        )
        nullable_fields = set(["description", "default_value"])
        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 PatchV2TargetIdentifierAttributesAttributeRequestBodyTypedDict(TypedDict):
    data: PatchV2TargetIdentifierAttributesAttributeDataTypedDict


class PatchV2TargetIdentifierAttributesAttributeRequestBody(BaseModel):
    data: PatchV2TargetIdentifierAttributesAttributeData


class PatchV2TargetIdentifierAttributesAttributeRequestTypedDict(TypedDict):
    target: PatchV2TargetIdentifierAttributesAttributeTarget
    r"""Whether the attribute is on an object or a list."""
    identifier: str
    attribute: str
    request_body: PatchV2TargetIdentifierAttributesAttributeRequestBodyTypedDict


class PatchV2TargetIdentifierAttributesAttributeRequest(BaseModel):
    target: Annotated[
        PatchV2TargetIdentifierAttributesAttributeTarget,
        FieldMetadata(path=PathParamMetadata(style="simple", explode=False)),
    ]
    r"""Whether the attribute is on an object or a list."""

    identifier: Annotated[
        str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
    ]

    attribute: Annotated[
        str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
    ]

    request_body: Annotated[
        PatchV2TargetIdentifierAttributesAttributeRequestBody,
        FieldMetadata(request=RequestMetadata(media_type="application/json")),
    ]


PatchV2TargetIdentifierAttributesAttributeNotFoundType = Literal[
    "invalid_request_error",
]


PatchV2TargetIdentifierAttributesAttributeNotFoundCode = Literal["not_found",]


PatchV2TargetIdentifierAttributesAttributeBadRequestType = Literal[
    "invalid_request_error",
]


CodeSystemEditUnauthorized = Literal["system_edit_unauthorized",]


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

    data: AttributeTypedDict


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

    data: Attribute
