"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
# @generated-id: f64f2e3b4790

from __future__ import annotations
from .balance_report_grouping import BalanceReportGrouping
from mollie import models
from mollie.types import BaseModel, UNSET_SENTINEL
from mollie.utils import (
    FieldMetadata,
    HeaderMetadata,
    PathParamMetadata,
    QueryParamMetadata,
)
import pydantic
from pydantic import field_serializer, model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class GetBalanceReportGlobalsTypedDict(TypedDict):
    testmode: NotRequired[bool]
    r"""Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
    parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
    setting the `testmode` query parameter to `true`.

    Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
    """


class GetBalanceReportGlobals(BaseModel):
    testmode: Annotated[
        Optional[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""Most API credentials are specifically created for either live mode or test mode. In those cases the `testmode` query
    parameter must not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by
    setting the `testmode` query parameter to `true`.

    Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
    """

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["testmode"])
        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 GetBalanceReportRequestTypedDict(TypedDict):
    balance_id: str
    r"""Provide the ID of the related balance."""
    from_: str
    r"""The start date of the report, in `YYYY-MM-DD` format. The from date is
    'inclusive', and in Central European Time. This means a report with for example `from=2024-01-01` will
    include transactions from 2024-01-01 0:00:00 CET and onwards.
    """
    until: str
    r"""The end date of the report, in `YYYY-MM-DD` format. The until date is 'exclusive', and in Central European Time.
    This means a report with for example `until=2024-02-01` will include transactions up until
    2024-01-31 23:59:59 CET.
    """
    grouping: NotRequired[BalanceReportGrouping]
    r"""You can retrieve reports in two different formats. With the `status-balances` format, transactions are grouped
    by status (e.g. `pending`, `available`), then by transaction type, and then by other sub-groupings where
    available (e.g. payment method).

    With the `transaction-categories` format, transactions are grouped by
    transaction type, then by status, and then again by other sub-groupings where available.
    """
    testmode: NotRequired[bool]
    r"""You can enable test mode by setting the `testmode` query parameter to `true`.

    Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
    """
    idempotency_key: NotRequired[str]
    r"""A unique key to ensure idempotent requests. This key should be a UUID v4 string."""


class GetBalanceReportRequest(BaseModel):
    balance_id: Annotated[
        str,
        pydantic.Field(alias="balanceId"),
        FieldMetadata(path=PathParamMetadata(style="simple", explode=False)),
    ]
    r"""Provide the ID of the related balance."""

    from_: Annotated[
        str,
        pydantic.Field(alias="from"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""The start date of the report, in `YYYY-MM-DD` format. The from date is
    'inclusive', and in Central European Time. This means a report with for example `from=2024-01-01` will
    include transactions from 2024-01-01 0:00:00 CET and onwards.
    """

    until: Annotated[
        str, FieldMetadata(query=QueryParamMetadata(style="form", explode=True))
    ]
    r"""The end date of the report, in `YYYY-MM-DD` format. The until date is 'exclusive', and in Central European Time.
    This means a report with for example `until=2024-02-01` will include transactions up until
    2024-01-31 23:59:59 CET.
    """

    grouping: Annotated[
        Optional[BalanceReportGrouping],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""You can retrieve reports in two different formats. With the `status-balances` format, transactions are grouped
    by status (e.g. `pending`, `available`), then by transaction type, and then by other sub-groupings where
    available (e.g. payment method).

    With the `transaction-categories` format, transactions are grouped by
    transaction type, then by status, and then again by other sub-groupings where available.
    """

    testmode: Annotated[
        Optional[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = None
    r"""You can enable test mode by setting the `testmode` query parameter to `true`.

    Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.
    """

    idempotency_key: Annotated[
        Optional[str],
        pydantic.Field(alias="idempotency-key"),
        FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
    ] = None
    r"""A unique key to ensure idempotent requests. This key should be a UUID v4 string."""

    @field_serializer("grouping")
    def serialize_grouping(self, value):
        if isinstance(value, str):
            try:
                return models.BalanceReportGrouping(value)
            except ValueError:
                return value
        return value

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