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

from __future__ import annotations
from datetime import datetime
from gr4vy.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
    UnrecognizedStr,
)
from gr4vy.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Literal, Union
from typing_extensions import Annotated, NotRequired, TypedDict


RouteType = Union[
    Literal[
        "round_trip",
        "one_way",
    ],
    UnrecognizedStr,
]


class AirlineLegTypedDict(TypedDict):
    arrival_airport: NotRequired[Nullable[str]]
    r"""Arrival airport code of leg. 3-letter ISO code according to IATA official directory."""
    arrival_at: NotRequired[Nullable[datetime]]
    r"""The date and time of travel in local time at the arrival airport."""
    arrival_city: NotRequired[Nullable[str]]
    r"""Arrival city name."""
    arrival_country: NotRequired[Nullable[str]]
    r"""Arrival country code in ISO 3166 format."""
    carrier_code: NotRequired[Nullable[str]]
    r"""3 character airline code as set by IATA."""
    carrier_name: NotRequired[Nullable[str]]
    r"""Name of the airline."""
    iata_designator: NotRequired[Nullable[str]]
    r"""Two-character IATA code of the airline."""
    icao_code: NotRequired[Nullable[str]]
    r"""Three-character ICAO code of the airline."""
    coupon_number: NotRequired[Nullable[str]]
    r"""Coupon number associated with the leg."""
    departure_airport: NotRequired[Nullable[str]]
    r"""Departure airport code of leg. 3-letter ISO code according to IATA official directory."""
    departure_at: NotRequired[Nullable[datetime]]
    r"""The date and time of travel in local time at the departure airport."""
    departure_city: NotRequired[Nullable[str]]
    r"""Departure city name."""
    departure_country: NotRequired[Nullable[str]]
    r"""Departure airport code of leg. 3-letter ISO code according to IATA official directory."""
    departure_tax_amount: NotRequired[Nullable[int]]
    r"""Departure tax amount charged by a country when a person is leaving the country."""
    fare_amount: NotRequired[Nullable[int]]
    r"""Amount of the ticket, for current leg of the trip, excluding taxes and fees."""
    fare_basis_code: NotRequired[Nullable[str]]
    r"""The alphanumeric code for the booking class of a ticket."""
    fee_amount: NotRequired[Nullable[int]]
    r"""Fee amount for current leg of the trip."""
    flight_class: NotRequired[Nullable[str]]
    r"""Indicates service class (first class, business class, etc.)."""
    flight_number: NotRequired[Nullable[str]]
    r"""Unique identifier of the flight number."""
    route_type: NotRequired[Nullable[RouteType]]
    r"""The route type of the flight."""
    seat_class: NotRequired[Nullable[str]]
    r"""Indicates seat class (first class, business class, etc.)."""
    stop_over: NotRequired[Nullable[bool]]
    r"""Indicates whether a stopover is allowed on this ticket."""
    tax_amount: NotRequired[Nullable[int]]
    r"""Amount of the taxes for current leg of the trip."""


class AirlineLeg(BaseModel):
    arrival_airport: OptionalNullable[str] = UNSET
    r"""Arrival airport code of leg. 3-letter ISO code according to IATA official directory."""

    arrival_at: OptionalNullable[datetime] = UNSET
    r"""The date and time of travel in local time at the arrival airport."""

    arrival_city: OptionalNullable[str] = UNSET
    r"""Arrival city name."""

    arrival_country: OptionalNullable[str] = UNSET
    r"""Arrival country code in ISO 3166 format."""

    carrier_code: OptionalNullable[str] = UNSET
    r"""3 character airline code as set by IATA."""

    carrier_name: OptionalNullable[str] = UNSET
    r"""Name of the airline."""

    iata_designator: OptionalNullable[str] = UNSET
    r"""Two-character IATA code of the airline."""

    icao_code: OptionalNullable[str] = UNSET
    r"""Three-character ICAO code of the airline."""

    coupon_number: OptionalNullable[str] = UNSET
    r"""Coupon number associated with the leg."""

    departure_airport: OptionalNullable[str] = UNSET
    r"""Departure airport code of leg. 3-letter ISO code according to IATA official directory."""

    departure_at: OptionalNullable[datetime] = UNSET
    r"""The date and time of travel in local time at the departure airport."""

    departure_city: OptionalNullable[str] = UNSET
    r"""Departure city name."""

    departure_country: OptionalNullable[str] = UNSET
    r"""Departure airport code of leg. 3-letter ISO code according to IATA official directory."""

    departure_tax_amount: OptionalNullable[int] = UNSET
    r"""Departure tax amount charged by a country when a person is leaving the country."""

    fare_amount: OptionalNullable[int] = UNSET
    r"""Amount of the ticket, for current leg of the trip, excluding taxes and fees."""

    fare_basis_code: OptionalNullable[str] = UNSET
    r"""The alphanumeric code for the booking class of a ticket."""

    fee_amount: OptionalNullable[int] = UNSET
    r"""Fee amount for current leg of the trip."""

    flight_class: OptionalNullable[str] = UNSET
    r"""Indicates service class (first class, business class, etc.)."""

    flight_number: OptionalNullable[str] = UNSET
    r"""Unique identifier of the flight number."""

    route_type: Annotated[
        OptionalNullable[RouteType], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The route type of the flight."""

    seat_class: OptionalNullable[str] = UNSET
    r"""Indicates seat class (first class, business class, etc.)."""

    stop_over: OptionalNullable[bool] = UNSET
    r"""Indicates whether a stopover is allowed on this ticket."""

    tax_amount: OptionalNullable[int] = UNSET
    r"""Amount of the taxes for current leg of the trip."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "arrival_airport",
            "arrival_at",
            "arrival_city",
            "arrival_country",
            "carrier_code",
            "carrier_name",
            "iata_designator",
            "icao_code",
            "coupon_number",
            "departure_airport",
            "departure_at",
            "departure_city",
            "departure_country",
            "departure_tax_amount",
            "fare_amount",
            "fare_basis_code",
            "fee_amount",
            "flight_class",
            "flight_number",
            "route_type",
            "seat_class",
            "stop_over",
            "tax_amount",
        ]
        nullable_fields = [
            "arrival_airport",
            "arrival_at",
            "arrival_city",
            "arrival_country",
            "carrier_code",
            "carrier_name",
            "iata_designator",
            "icao_code",
            "coupon_number",
            "departure_airport",
            "departure_at",
            "departure_city",
            "departure_country",
            "departure_tax_amount",
            "fare_amount",
            "fare_basis_code",
            "fee_amount",
            "flight_class",
            "flight_number",
            "route_type",
            "seat_class",
            "stop_over",
            "tax_amount",
        ]
        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
