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

from __future__ import annotations
from enum import Enum
from gusto_embedded.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import List, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict


class TaxRequirementMetadataType(str, Enum):
    r"""Describes the type of requirement - each type may have additional metadata properties to describe possible values, formats, etc.

    - `text`: free-text input, no additional requirements
    - `currency`: a value representing a dollar amount, e.g. `374.55` representing `$374.55`
    - `radio`: choose one of options provided, see `options`
    - `select`: choose one of options provided, see `options`
    - `percent`: A decimal value representing a percentage, e.g. `0.034` representing `3.4%`
    - `account_number`: An account number for a tax agency, more information provided by `mask` and `prefix`
    - `tax_rate`: A decimal value representing a tax rate, e.g. `0.034` representing a tax rate of `3.4%`, see `validation` for additional validation guidance
    - `workers_compensation_rate`: A decimal value representing a percentage, see `risk_class_code`, `risk_class_description`, and `rate_type`

    """

    TEXT = "text"
    CURRENCY = "currency"
    RADIO = "radio"
    SELECT = "select"
    PERCENT = "percent"
    ACCOUNT_NUMBER = "account_number"
    TAX_RATE = "tax_rate"
    WORKERS_COMPENSATION_RATE = "workers_compensation_rate"


TaxRequirementMetadataValueTypedDict = TypeAliasType(
    "TaxRequirementMetadataValueTypedDict", Union[str, bool]
)
r"""The actual value to be submitted"""


TaxRequirementMetadataValue = TypeAliasType(
    "TaxRequirementMetadataValue", Union[str, bool]
)
r"""The actual value to be submitted"""


class TaxRequirementMetadataOptionsTypedDict(TypedDict):
    label: str
    r"""A customer facing label for the answer"""
    value: TaxRequirementMetadataValueTypedDict
    r"""The actual value to be submitted"""
    short_label: NotRequired[str]
    r"""A less verbose label that may sometimes be available"""


class TaxRequirementMetadataOptions(BaseModel):
    label: str
    r"""A customer facing label for the answer"""

    value: TaxRequirementMetadataValue
    r"""The actual value to be submitted"""

    short_label: Optional[str] = None
    r"""A less verbose label that may sometimes be available"""


class RateType(str, Enum):
    r"""[for `workers_compensation_rate`] The type of rate being collected. Either:
    - `percent`: A percentage formatted as a decimal, e.g. `0.01` for 1%
    - `currency_per_hour`: A dollar amount per hour, e.g. `3.24` for $3.24/hr

    """

    PERCENT = "percent"
    CURRENCY_PER_HOUR = "currency_per_hour"


class TaxRequirementMetadataValidationType(str, Enum):
    r"""Describes the type of tax_rate validation rule"""

    ONE_OF = "one_of"
    MIN_MAX = "min_max"


class ValidationTypedDict(TypedDict):
    r"""[for `tax_rate`] Describes the validation required for the tax rate"""

    type: TaxRequirementMetadataValidationType
    r"""Describes the type of tax_rate validation rule"""
    min: NotRequired[str]
    r"""[for `min_max`] The inclusive lower bound of the tax rate"""
    max: NotRequired[str]
    r"""[for `min_max`] The inclusive upper bound of the tax rate"""
    rates: NotRequired[List[str]]
    r"""[for `one_of`] The possible, unformatted tax rates for selection.
    - e.g. [\"0.0\", \"0.001\"] representing 0% and 0.1%

    """


class Validation(BaseModel):
    r"""[for `tax_rate`] Describes the validation required for the tax rate"""

    type: TaxRequirementMetadataValidationType
    r"""Describes the type of tax_rate validation rule"""

    min: Optional[str] = None
    r"""[for `min_max`] The inclusive lower bound of the tax rate"""

    max: Optional[str] = None
    r"""[for `min_max`] The inclusive upper bound of the tax rate"""

    rates: Optional[List[str]] = None
    r"""[for `one_of`] The possible, unformatted tax rates for selection.
    - e.g. [\"0.0\", \"0.001\"] representing 0% and 0.1%

    """


class TaxRequirementMetadataTypedDict(TypedDict):
    type: TaxRequirementMetadataType
    r"""Describes the type of requirement - each type may have additional metadata properties to describe possible values, formats, etc.

    - `text`: free-text input, no additional requirements
    - `currency`: a value representing a dollar amount, e.g. `374.55` representing `$374.55`
    - `radio`: choose one of options provided, see `options`
    - `select`: choose one of options provided, see `options`
    - `percent`: A decimal value representing a percentage, e.g. `0.034` representing `3.4%`
    - `account_number`: An account number for a tax agency, more information provided by `mask` and `prefix`
    - `tax_rate`: A decimal value representing a tax rate, e.g. `0.034` representing a tax rate of `3.4%`, see `validation` for additional validation guidance
    - `workers_compensation_rate`: A decimal value representing a percentage, see `risk_class_code`, `risk_class_description`, and `rate_type`

    """
    options: NotRequired[List[TaxRequirementMetadataOptionsTypedDict]]
    r"""[for `select` or `radio`] An array of objects describing the possible values."""
    risk_class_code: NotRequired[str]
    r"""[for `workers_compensation_rate`] The industry risk class code for the rate being requested"""
    risk_class_description: NotRequired[str]
    r"""[for `workers_compensation_rate`] A description of the industry risk class for the rate being requested"""
    rate_type: NotRequired[RateType]
    r"""[for `workers_compensation_rate`] The type of rate being collected. Either:
    - `percent`: A percentage formatted as a decimal, e.g. `0.01` for 1%
    - `currency_per_hour`: A dollar amount per hour, e.g. `3.24` for $3.24/hr

    """
    mask: NotRequired[Nullable[str]]
    r"""[for `account_number`] A pattern describing the format of the account number

    The mask is a sequence of characters representing the requirements of the actual account number. Each character in the mask represents a single character in the account number as follows:
    - `#`: a digit (`\d`)
    - `@`: a upper or lower case letter (`[a-zA-Z]`)
    - `^`: an uppercase letter (`[A-Z]`)
    - `%`: a digit or uppercase letter (`[0-9A-Z]`)
    - any other character represents the literal character

    Examples:
    - mask: `WHT-######` represents `WHT-` followed by 5 digits, e.g. `WHT-33421`
    - mask: `%####-^^` supports values of `75544-AB` and `Z7654-HK`

    """
    prefix: NotRequired[Nullable[str]]
    r"""[for `account_number`] A value that precedes the value to be collected - useful for display, but should not be submitted as part of the value. E.g. some tax agencies use an account number that is a company's federal ein plus two digits. In that case the mask would be `##` and the prefix `XXXXX1234`."""
    validation: NotRequired[ValidationTypedDict]
    r"""[for `tax_rate`] Describes the validation required for the tax rate"""


class TaxRequirementMetadata(BaseModel):
    type: TaxRequirementMetadataType
    r"""Describes the type of requirement - each type may have additional metadata properties to describe possible values, formats, etc.

    - `text`: free-text input, no additional requirements
    - `currency`: a value representing a dollar amount, e.g. `374.55` representing `$374.55`
    - `radio`: choose one of options provided, see `options`
    - `select`: choose one of options provided, see `options`
    - `percent`: A decimal value representing a percentage, e.g. `0.034` representing `3.4%`
    - `account_number`: An account number for a tax agency, more information provided by `mask` and `prefix`
    - `tax_rate`: A decimal value representing a tax rate, e.g. `0.034` representing a tax rate of `3.4%`, see `validation` for additional validation guidance
    - `workers_compensation_rate`: A decimal value representing a percentage, see `risk_class_code`, `risk_class_description`, and `rate_type`

    """

    options: Optional[List[TaxRequirementMetadataOptions]] = None
    r"""[for `select` or `radio`] An array of objects describing the possible values."""

    risk_class_code: Optional[str] = None
    r"""[for `workers_compensation_rate`] The industry risk class code for the rate being requested"""

    risk_class_description: Optional[str] = None
    r"""[for `workers_compensation_rate`] A description of the industry risk class for the rate being requested"""

    rate_type: Optional[RateType] = None
    r"""[for `workers_compensation_rate`] The type of rate being collected. Either:
    - `percent`: A percentage formatted as a decimal, e.g. `0.01` for 1%
    - `currency_per_hour`: A dollar amount per hour, e.g. `3.24` for $3.24/hr

    """

    mask: OptionalNullable[str] = UNSET
    r"""[for `account_number`] A pattern describing the format of the account number

    The mask is a sequence of characters representing the requirements of the actual account number. Each character in the mask represents a single character in the account number as follows:
    - `#`: a digit (`\d`)
    - `@`: a upper or lower case letter (`[a-zA-Z]`)
    - `^`: an uppercase letter (`[A-Z]`)
    - `%`: a digit or uppercase letter (`[0-9A-Z]`)
    - any other character represents the literal character

    Examples:
    - mask: `WHT-######` represents `WHT-` followed by 5 digits, e.g. `WHT-33421`
    - mask: `%####-^^` supports values of `75544-AB` and `Z7654-HK`

    """

    prefix: OptionalNullable[str] = UNSET
    r"""[for `account_number`] A value that precedes the value to be collected - useful for display, but should not be submitted as part of the value. E.g. some tax agencies use an account number that is a company's federal ein plus two digits. In that case the mask would be `##` and the prefix `XXXXX1234`."""

    validation: Optional[Validation] = None
    r"""[for `tax_rate`] Describes the validation required for the tax rate"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "options",
            "risk_class_code",
            "risk_class_description",
            "rate_type",
            "mask",
            "prefix",
            "validation",
        ]
        nullable_fields = ["mask", "prefix"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in 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
