# -*- coding: utf-8 -*-
# File generated from our OpenAPI spec
from stripe._singleton_api_resource import SingletonAPIResource
from stripe._stripe_object import StripeObject, UntypedStripeObject
from stripe._updateable_api_resource import UpdateableAPIResource
from typing import ClassVar, List, Optional, Union, cast
from typing_extensions import Literal, Unpack, TYPE_CHECKING

if TYPE_CHECKING:
    from stripe.params._balance_settings_modify_params import (
        BalanceSettingsModifyParams,
    )
    from stripe.params._balance_settings_retrieve_params import (
        BalanceSettingsRetrieveParams,
    )


class BalanceSettings(
    SingletonAPIResource["BalanceSettings"],
    UpdateableAPIResource["BalanceSettings"],
):
    """
    Options for customizing account balances and payout settings for a Stripe platform's connected accounts.
    """

    OBJECT_NAME: ClassVar[Literal["balance_settings"]] = "balance_settings"

    class Payments(StripeObject):
        class Payouts(StripeObject):
            class AutomaticTransferRulesByCurrency(StripeObject):
                payout_method: str
                """
                The ID of the FinancialAccount that funds will be transferred to during automatic transfers.
                """
                transfer_up_to_amount: Optional[int]
                """
                The maximum amount in minor units to transfer to the FinancialAccount. Only applicable when `type` is `transfer_up_to_amount`.
                """
                type: Union[
                    Literal["transfer_all", "transfer_up_to_amount"], str
                ]
                """
                The type of automatic transfer rule.
                """

            class Schedule(StripeObject):
                interval: Optional[
                    Union[Literal["daily", "manual", "monthly", "weekly"], str]
                ]
                """
                How frequently funds will be paid out. One of `manual` (payouts only created via API call), `daily`, `weekly`, or `monthly`.
                """
                monthly_payout_days: Optional[List[int]]
                """
                The day of the month funds will be paid out. Only shown if `interval` is monthly. Payouts scheduled between the 29th and 31st of the month are sent on the last day of shorter months.
                """
                weekly_payout_days: Optional[
                    List[
                        Union[
                            Literal[
                                "friday",
                                "monday",
                                "thursday",
                                "tuesday",
                                "wednesday",
                            ],
                            str,
                        ]
                    ]
                ]
                """
                The days of the week when available funds are paid out, specified as an array, for example, [`monday`, `tuesday`]. Only shown if `interval` is weekly.
                """

            automatic_transfer_rules_by_currency: Optional[
                UntypedStripeObject[List[AutomaticTransferRulesByCurrency]]
            ]
            """
            Configures per-currency rules for automatically transferring funds from the payments balance to a FinancialAccount.
            """
            minimum_balance_by_currency: Optional[UntypedStripeObject[int]]
            """
            The minimum balance amount to retain per currency after automatic payouts. Only funds that exceed these amounts are paid out. Learn more about the [minimum balances for automatic payouts](https://docs.stripe.com/payouts/minimum-balances-for-automatic-payouts).
            """
            schedule: Optional[Schedule]
            """
            Details on when funds from charges are available, and when they are paid out to an external account. See our [Setting Bank and Debit Card Payouts](https://docs.stripe.com/connect/bank-transfers#payout-information) documentation for details.
            """
            statement_descriptor: Optional[str]
            """
            The text that appears on the bank account statement for payouts. If not set, this defaults to the platform's bank descriptor as set in the Dashboard.
            """
            status: Union[Literal["disabled", "enabled"], str]
            """
            Whether the funds in this account can be paid out.
            """
            _inner_class_types = {
                "automatic_transfer_rules_by_currency": AutomaticTransferRulesByCurrency,
                "schedule": Schedule,
            }
            _inner_class_dicts = ["automatic_transfer_rules_by_currency"]

        class SettlementTiming(StripeObject):
            class StartOfDay(StripeObject):
                hour: int
                """
                Hour at which the customized start of day begins according to the given timezone. Must be a [supported customized start of day hour](https://docs.stripe.com/connect/customized-start-of-day#available-timezones-and-cutoffs).
                """
                minutes: int
                """
                Minutes at which the customized start of day begins according to the given timezone. Must be either 0 or 30.
                """
                timezone: str
                """
                Timezone for the customized start of day. Must be a [supported customized start of day timezone](https://docs.stripe.com/connect/customized-start-of-day#available-timezones-and-cutoffs).
                """

            delay_days: int
            """
            The number of days charge funds are held before becoming available.
            """
            delay_days_override: Optional[int]
            """
            The number of days charge funds are held before becoming available. If present, overrides the default, or minimum available, for the account.
            """
            start_of_day: Optional[StartOfDay]
            """
            Customized start of day configuration for automatic payouts to group and send payments in local timezones with a customized day starting time. For details, see our [Customized start of day](https://docs.stripe.com/connect/customized-start-of-day) documentation.
            """
            _inner_class_types = {"start_of_day": StartOfDay}

        debit_negative_balances: Optional[bool]
        """
        A Boolean indicating if Stripe should try to reclaim negative balances from an attached bank account. See [Understanding Connect account balances](https://docs.stripe.com/connect/account-balances) for details. The default value is `false` when [controller.requirement_collection](https://docs.stripe.com/api/accounts/object#account_object-controller-requirement_collection) is `application`, which includes Custom accounts, otherwise `true`.
        """
        payouts: Optional[Payouts]
        """
        Settings specific to the account's payouts.
        """
        settlement_timing: SettlementTiming
        _inner_class_types = {
            "payouts": Payouts,
            "settlement_timing": SettlementTiming,
        }

    object: Literal["balance_settings"]
    """
    String representing the object's type. Objects of the same type share the same value.
    """
    payments: Payments

    @classmethod
    def modify(
        cls, **params: Unpack["BalanceSettingsModifyParams"]
    ) -> "BalanceSettings":
        """
        Updates balance settings for a given connected account.
         Related guide: [Making API calls for connected accounts](https://docs.stripe.com/connect/authentication)
        """
        return cast(
            "BalanceSettings",
            cls._static_request(
                "post",
                cls.class_url(),
                params=params,
            ),
        )

    @classmethod
    async def modify_async(
        cls, **params: Unpack["BalanceSettingsModifyParams"]
    ) -> "BalanceSettings":
        """
        Updates balance settings for a given connected account.
         Related guide: [Making API calls for connected accounts](https://docs.stripe.com/connect/authentication)
        """
        return cast(
            "BalanceSettings",
            await cls._static_request_async(
                "post",
                cls.class_url(),
                params=params,
            ),
        )

    @classmethod
    def retrieve(
        cls, **params: Unpack["BalanceSettingsRetrieveParams"]
    ) -> "BalanceSettings":
        """
        Retrieves balance settings for a given connected account.
         Related guide: [Making API calls for connected accounts](https://docs.stripe.com/connect/authentication)
        """
        instance = cls(None, **params)
        instance.refresh()
        return instance

    @classmethod
    async def retrieve_async(
        cls, **params: Unpack["BalanceSettingsRetrieveParams"]
    ) -> "BalanceSettings":
        """
        Retrieves balance settings for a given connected account.
         Related guide: [Making API calls for connected accounts](https://docs.stripe.com/connect/authentication)
        """
        instance = cls(None, **params)
        await instance.refresh_async()
        return instance

    @classmethod
    def class_url(cls):
        return "/v1/balance_settings"

    _inner_class_types = {"payments": Payments}
