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

from __future__ import annotations
from .attachedcustomfield import AttachedCustomField, AttachedCustomFieldTypedDict
from .benefit import Benefit, BenefitTypedDict
from .legacyrecurringproductprice import (
    LegacyRecurringProductPrice,
    LegacyRecurringProductPriceTypedDict,
)
from .metadataoutputtype import MetadataOutputType, MetadataOutputTypeTypedDict
from .productmediafileread import ProductMediaFileRead, ProductMediaFileReadTypedDict
from .productprice import ProductPrice, ProductPriceTypedDict
from .productvisibility import ProductVisibility
from .subscriptionrecurringinterval import SubscriptionRecurringInterval
from .trialinterval import TrialInterval
from datetime import datetime
from polar_sdk.types import BaseModel, Nullable, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Dict, List, Union
from typing_extensions import TypeAliasType, TypedDict


PricesTypedDict = TypeAliasType(
    "PricesTypedDict",
    Union[LegacyRecurringProductPriceTypedDict, ProductPriceTypedDict],
)


Prices = TypeAliasType("Prices", Union[LegacyRecurringProductPrice, ProductPrice])


class ProductTypedDict(TypedDict):
    r"""A product."""

    id: str
    r"""The ID of the object."""
    created_at: datetime
    r"""Creation timestamp of the object."""
    modified_at: Nullable[datetime]
    r"""Last modification timestamp of the object."""
    trial_interval: Nullable[TrialInterval]
    r"""The interval unit for the trial period."""
    trial_interval_count: Nullable[int]
    r"""The number of interval units for the trial period."""
    name: str
    r"""The name of the product."""
    description: Nullable[str]
    r"""The description of the product."""
    visibility: ProductVisibility
    recurring_interval: Nullable[SubscriptionRecurringInterval]
    r"""The recurring interval of the product. If `None`, the product is a one-time purchase."""
    recurring_interval_count: Nullable[int]
    r"""Number of interval units of the subscription. If this is set to 1 the charge will happen every interval (e.g. every month), if set to 2 it will be every other month, and so on. None for one-time products."""
    is_recurring: bool
    r"""Whether the product is a subscription."""
    is_archived: bool
    r"""Whether the product is archived and no longer available."""
    organization_id: str
    r"""The ID of the organization owning the product."""
    metadata: Dict[str, MetadataOutputTypeTypedDict]
    prices: List[PricesTypedDict]
    r"""List of prices for this product."""
    benefits: List[BenefitTypedDict]
    r"""List of benefits granted by the product."""
    medias: List[ProductMediaFileReadTypedDict]
    r"""List of medias associated to the product."""
    attached_custom_fields: List[AttachedCustomFieldTypedDict]
    r"""List of custom fields attached to the product."""


class Product(BaseModel):
    r"""A product."""

    id: str
    r"""The ID of the object."""

    created_at: datetime
    r"""Creation timestamp of the object."""

    modified_at: Nullable[datetime]
    r"""Last modification timestamp of the object."""

    trial_interval: Nullable[TrialInterval]
    r"""The interval unit for the trial period."""

    trial_interval_count: Nullable[int]
    r"""The number of interval units for the trial period."""

    name: str
    r"""The name of the product."""

    description: Nullable[str]
    r"""The description of the product."""

    visibility: ProductVisibility

    recurring_interval: Nullable[SubscriptionRecurringInterval]
    r"""The recurring interval of the product. If `None`, the product is a one-time purchase."""

    recurring_interval_count: Nullable[int]
    r"""Number of interval units of the subscription. If this is set to 1 the charge will happen every interval (e.g. every month), if set to 2 it will be every other month, and so on. None for one-time products."""

    is_recurring: bool
    r"""Whether the product is a subscription."""

    is_archived: bool
    r"""Whether the product is archived and no longer available."""

    organization_id: str
    r"""The ID of the organization owning the product."""

    metadata: Dict[str, MetadataOutputType]

    prices: List[Prices]
    r"""List of prices for this product."""

    benefits: List[Benefit]
    r"""List of benefits granted by the product."""

    medias: List[ProductMediaFileRead]
    r"""List of medias associated to the product."""

    attached_custom_fields: List[AttachedCustomField]
    r"""List of custom fields attached to the product."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = []
        nullable_fields = [
            "modified_at",
            "trial_interval",
            "trial_interval_count",
            "description",
            "recurring_interval",
            "recurring_interval_count",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
