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

from __future__ import annotations
from .price import Price, PriceTypedDict
from datetime import datetime
from paygentic_sdk.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
import pydantic
from pydantic import model_serializer
from typing import List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict


PlanObject = Literal["plan",]


class PlanPaymentTermTypedDict(TypedDict):
    in_arrears: NotRequired[bool]
    instant: NotRequired[bool]


class PlanPaymentTerm(BaseModel):
    in_arrears: Optional[bool] = None

    instant: Optional[bool] = None

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


TaxBehavior = Union[
    Literal[
        "exclusive",
        "inclusive",
    ],
    UnrecognizedStr,
]
r"""Whether tax is added on top of the price (exclusive) or included in the price (inclusive)"""


class PlanTypedDict(TypedDict):
    id: str
    r"""Unique identifier for a plan"""
    object: PlanObject
    billing_interval: str
    created_at: datetime
    currency: str
    merchant_id: str
    r"""Unique identifier for an organization"""
    name: str
    product_id: str
    r"""Unique identifier for a product"""
    updated_at: datetime
    default_tax_code: NotRequired[str]
    r"""Default tax code for plan line items. Common values: 'eservice' (electronically supplied services), 'saas' (software as a service), 'consulting', 'ebook', 'standard', 'reduced', 'exempt'. Full list available via GET /tax/codes endpoint."""
    default_tax_rate: NotRequired[float]
    r"""Fallback tax rate (as percentage) if automatic tax calculation is unavailable"""
    deleted_at: NotRequired[datetime]
    description: NotRequired[str]
    invoice_display_name: NotRequired[str]
    payment_term: NotRequired[PlanPaymentTermTypedDict]
    prices: NotRequired[List[PriceTypedDict]]
    tax_behavior: NotRequired[TaxBehavior]
    r"""Whether tax is added on top of the price (exclusive) or included in the price (inclusive)"""
    wallet_namespace_id: NotRequired[str]
    r"""Unique identifier for a wallet namespace"""
    renewal_reminder_enabled: NotRequired[bool]
    r"""Whether renewal reminder emails are enabled for subscriptions using this plan"""
    renewal_reminder_days: NotRequired[int]
    r"""Number of days before renewal to send the reminder email"""
    billing_version: NotRequired[int]
    r"""Billing engine version. Managed by Paygentic support."""


class Plan(BaseModel):
    id: str
    r"""Unique identifier for a plan"""

    object: PlanObject

    billing_interval: Annotated[str, pydantic.Field(alias="billingInterval")]

    created_at: Annotated[datetime, pydantic.Field(alias="createdAt")]

    currency: str

    merchant_id: Annotated[str, pydantic.Field(alias="merchantId")]
    r"""Unique identifier for an organization"""

    name: str

    product_id: Annotated[str, pydantic.Field(alias="productId")]
    r"""Unique identifier for a product"""

    updated_at: Annotated[datetime, pydantic.Field(alias="updatedAt")]

    default_tax_code: Annotated[
        Optional[str], pydantic.Field(alias="defaultTaxCode")
    ] = None
    r"""Default tax code for plan line items. Common values: 'eservice' (electronically supplied services), 'saas' (software as a service), 'consulting', 'ebook', 'standard', 'reduced', 'exempt'. Full list available via GET /tax/codes endpoint."""

    default_tax_rate: Annotated[
        Optional[float], pydantic.Field(alias="defaultTaxRate")
    ] = None
    r"""Fallback tax rate (as percentage) if automatic tax calculation is unavailable"""

    deleted_at: Annotated[Optional[datetime], pydantic.Field(alias="deletedAt")] = None

    description: Optional[str] = None

    invoice_display_name: Annotated[
        Optional[str], pydantic.Field(alias="invoiceDisplayName")
    ] = None

    payment_term: Annotated[
        Optional[PlanPaymentTerm], pydantic.Field(alias="paymentTerm")
    ] = None

    prices: Optional[List[Price]] = None

    tax_behavior: Annotated[
        Optional[TaxBehavior], pydantic.Field(alias="taxBehavior")
    ] = None
    r"""Whether tax is added on top of the price (exclusive) or included in the price (inclusive)"""

    wallet_namespace_id: Annotated[
        Optional[str], pydantic.Field(alias="walletNamespaceId")
    ] = None
    r"""Unique identifier for a wallet namespace"""

    renewal_reminder_enabled: Annotated[
        Optional[bool], pydantic.Field(alias="renewalReminderEnabled")
    ] = None
    r"""Whether renewal reminder emails are enabled for subscriptions using this plan"""

    renewal_reminder_days: Annotated[
        Optional[int], pydantic.Field(alias="renewalReminderDays")
    ] = None
    r"""Number of days before renewal to send the reminder email"""

    billing_version: Annotated[
        Optional[int], pydantic.Field(alias="billingVersion")
    ] = None
    r"""Billing engine version. Managed by Paygentic support."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "defaultTaxCode",
                "defaultTaxRate",
                "deletedAt",
                "description",
                "invoiceDisplayName",
                "paymentTerm",
                "prices",
                "taxBehavior",
                "walletNamespaceId",
                "renewalReminderEnabled",
                "renewalReminderDays",
                "billingVersion",
            ]
        )
        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


try:
    Plan.model_rebuild()
except NameError:
    pass
