# This file was auto-generated by Fern from our API Definition.

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..money_out_types.types.authorize_payment_method import AuthorizePaymentMethod
from ..money_out_types.types.request_out_authorize_vendor_data import RequestOutAuthorizeVendorData
from ..types.account_id import AccountId
from ..types.bill_pay_out_data_request import BillPayOutDataRequest
from ..types.entrypointfield import Entrypointfield
from ..types.idempotency_key import IdempotencyKey
from ..types.source import Source
from ..types.subdomain import Subdomain
from .raw_client import AsyncRawPayoutSubscriptionClient, RawPayoutSubscriptionClient
from .types.add_payout_subscription_response import AddPayoutSubscriptionResponse
from .types.delete_payout_subscription_response import DeletePayoutSubscriptionResponse
from .types.get_payout_subscription_response import GetPayoutSubscriptionResponse
from .types.payout_payment_detail import PayoutPaymentDetail
from .types.payout_schedule_detail import PayoutScheduleDetail
from .types.payout_set_pause import PayoutSetPause
from .types.update_payout_subscription_response import UpdatePayoutSubscriptionResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class PayoutSubscriptionClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawPayoutSubscriptionClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawPayoutSubscriptionClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawPayoutSubscriptionClient
        """
        return self._raw_client

    def create_payout_subscription(
        self,
        *,
        entry_point: Entrypointfield,
        payment_method: AuthorizePaymentMethod,
        vendor_data: RequestOutAuthorizeVendorData,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        subdomain: typing.Optional[Subdomain] = OMIT,
        account_id: typing.Optional[AccountId] = OMIT,
        source: typing.Optional[Source] = OMIT,
        set_pause: typing.Optional[PayoutSetPause] = OMIT,
        payment_details: typing.Optional[PayoutPaymentDetail] = OMIT,
        bill_data: typing.Optional[typing.Sequence[BillPayOutDataRequest]] = OMIT,
        schedule_details: typing.Optional[PayoutScheduleDetail] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddPayoutSubscriptionResponse:
        """
        Creates a payout subscription to automatically send payouts to a vendor on a recurring schedule. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for a step-by-step guide.

        Parameters
        ----------
        entry_point : Entrypointfield

        payment_method : AuthorizePaymentMethod
            Payment method for the payout subscription. Supports `ach`, `vcard`, and `check`. The `managed` method isn't supported for payout subscriptions.

        vendor_data : RequestOutAuthorizeVendorData
            Object identifying the vendor for this subscription. Only a `vendorId` or `vendorNumber` is needed to link to an existing vendor.

        idempotency_key : typing.Optional[IdempotencyKey]

        subdomain : typing.Optional[Subdomain]

        account_id : typing.Optional[AccountId]

        source : typing.Optional[Source]

        set_pause : typing.Optional[PayoutSetPause]

        payment_details : typing.Optional[PayoutPaymentDetail]
            Object describing details of the payout.

        bill_data : typing.Optional[typing.Sequence[BillPayOutDataRequest]]
            Array of bills associated with the payout subscription. If omitted and `doNotCreateBills` isn't set to `true`, the system creates a bill automatically.

        schedule_details : typing.Optional[PayoutScheduleDetail]
            Object describing the schedule for the payout subscription.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AddPayoutSubscriptionResponse
            Success

        Examples
        --------
        import datetime

        from payabli import BillPayOutDataRequest, payabli
        from payabli.money_out_types import (
            AuthorizePaymentMethod,
            RequestOutAuthorizeVendorData,
        )
        from payabli.payout_subscription import (
            PayoutPaymentDetail,
            PayoutScheduleDetail,
        )

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.payout_subscription.create_payout_subscription(
            entry_point="d193cf9a46",
            payment_method=AuthorizePaymentMethod(
                method="ach",
                ach_holder="Herman Coatings",
                ach_routing="021000021",
                ach_account="3453445666",
                ach_account_type="checking",
            ),
            payment_details=PayoutPaymentDetail(
                total_amount=500.0,
                service_fee=0.0,
                currency="USD",
            ),
            vendor_data=RequestOutAuthorizeVendorData(
                vendor_id=1501,
            ),
            bill_data=[
                BillPayOutDataRequest(
                    invoice_number="INV-5001",
                    net_amount="500",
                    invoice_date=datetime.date.fromisoformat(
                        "2025-08-01",
                    ),
                    due_date=datetime.date.fromisoformat(
                        "2025-08-15",
                    ),
                )
            ],
            schedule_details=PayoutScheduleDetail(
                start_date="09/01/2025",
                end_date="09/01/2026",
                frequency="monthly",
            ),
        )
        """
        _response = self._raw_client.create_payout_subscription(
            entry_point=entry_point,
            payment_method=payment_method,
            vendor_data=vendor_data,
            idempotency_key=idempotency_key,
            subdomain=subdomain,
            account_id=account_id,
            source=source,
            set_pause=set_pause,
            payment_details=payment_details,
            bill_data=bill_data,
            schedule_details=schedule_details,
            request_options=request_options,
        )
        return _response.data

    def get_payout_subscription(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetPayoutSubscriptionResponse:
        """
        Retrieves a single payout subscription's details. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetPayoutSubscriptionResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.payout_subscription.get_payout_subscription(
            id=42,
        )
        """
        _response = self._raw_client.get_payout_subscription(id, request_options=request_options)
        return _response.data

    def update_payout_subscription(
        self,
        id: int,
        *,
        set_pause: typing.Optional[PayoutSetPause] = OMIT,
        payment_details: typing.Optional[PayoutPaymentDetail] = OMIT,
        payment_method: typing.Optional[AuthorizePaymentMethod] = OMIT,
        schedule_details: typing.Optional[PayoutScheduleDetail] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdatePayoutSubscriptionResponse:
        """
        Updates a payout subscription's details. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        set_pause : typing.Optional[PayoutSetPause]

        payment_details : typing.Optional[PayoutPaymentDetail]
            Object describing details of the payout.

        payment_method : typing.Optional[AuthorizePaymentMethod]

        schedule_details : typing.Optional[PayoutScheduleDetail]
            Object describing the schedule for the payout subscription.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        UpdatePayoutSubscriptionResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.payout_subscription.update_payout_subscription(
            id=42,
            set_pause=True,
        )
        """
        _response = self._raw_client.update_payout_subscription(
            id,
            set_pause=set_pause,
            payment_details=payment_details,
            payment_method=payment_method,
            schedule_details=schedule_details,
            request_options=request_options,
        )
        return _response.data

    def delete_payout_subscription(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeletePayoutSubscriptionResponse:
        """
        Deletes a payout subscription and prevents future payouts. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        DeletePayoutSubscriptionResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.payout_subscription.delete_payout_subscription(
            id=42,
        )
        """
        _response = self._raw_client.delete_payout_subscription(id, request_options=request_options)
        return _response.data


class AsyncPayoutSubscriptionClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawPayoutSubscriptionClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawPayoutSubscriptionClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawPayoutSubscriptionClient
        """
        return self._raw_client

    async def create_payout_subscription(
        self,
        *,
        entry_point: Entrypointfield,
        payment_method: AuthorizePaymentMethod,
        vendor_data: RequestOutAuthorizeVendorData,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        subdomain: typing.Optional[Subdomain] = OMIT,
        account_id: typing.Optional[AccountId] = OMIT,
        source: typing.Optional[Source] = OMIT,
        set_pause: typing.Optional[PayoutSetPause] = OMIT,
        payment_details: typing.Optional[PayoutPaymentDetail] = OMIT,
        bill_data: typing.Optional[typing.Sequence[BillPayOutDataRequest]] = OMIT,
        schedule_details: typing.Optional[PayoutScheduleDetail] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddPayoutSubscriptionResponse:
        """
        Creates a payout subscription to automatically send payouts to a vendor on a recurring schedule. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for a step-by-step guide.

        Parameters
        ----------
        entry_point : Entrypointfield

        payment_method : AuthorizePaymentMethod
            Payment method for the payout subscription. Supports `ach`, `vcard`, and `check`. The `managed` method isn't supported for payout subscriptions.

        vendor_data : RequestOutAuthorizeVendorData
            Object identifying the vendor for this subscription. Only a `vendorId` or `vendorNumber` is needed to link to an existing vendor.

        idempotency_key : typing.Optional[IdempotencyKey]

        subdomain : typing.Optional[Subdomain]

        account_id : typing.Optional[AccountId]

        source : typing.Optional[Source]

        set_pause : typing.Optional[PayoutSetPause]

        payment_details : typing.Optional[PayoutPaymentDetail]
            Object describing details of the payout.

        bill_data : typing.Optional[typing.Sequence[BillPayOutDataRequest]]
            Array of bills associated with the payout subscription. If omitted and `doNotCreateBills` isn't set to `true`, the system creates a bill automatically.

        schedule_details : typing.Optional[PayoutScheduleDetail]
            Object describing the schedule for the payout subscription.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AddPayoutSubscriptionResponse
            Success

        Examples
        --------
        import asyncio
        import datetime

        from payabli import Asyncpayabli, BillPayOutDataRequest
        from payabli.money_out_types import (
            AuthorizePaymentMethod,
            RequestOutAuthorizeVendorData,
        )
        from payabli.payout_subscription import (
            PayoutPaymentDetail,
            PayoutScheduleDetail,
        )

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.payout_subscription.create_payout_subscription(
                entry_point="d193cf9a46",
                payment_method=AuthorizePaymentMethod(
                    method="ach",
                    ach_holder="Herman Coatings",
                    ach_routing="021000021",
                    ach_account="3453445666",
                    ach_account_type="checking",
                ),
                payment_details=PayoutPaymentDetail(
                    total_amount=500.0,
                    service_fee=0.0,
                    currency="USD",
                ),
                vendor_data=RequestOutAuthorizeVendorData(
                    vendor_id=1501,
                ),
                bill_data=[
                    BillPayOutDataRequest(
                        invoice_number="INV-5001",
                        net_amount="500",
                        invoice_date=datetime.date.fromisoformat(
                            "2025-08-01",
                        ),
                        due_date=datetime.date.fromisoformat(
                            "2025-08-15",
                        ),
                    )
                ],
                schedule_details=PayoutScheduleDetail(
                    start_date="09/01/2025",
                    end_date="09/01/2026",
                    frequency="monthly",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create_payout_subscription(
            entry_point=entry_point,
            payment_method=payment_method,
            vendor_data=vendor_data,
            idempotency_key=idempotency_key,
            subdomain=subdomain,
            account_id=account_id,
            source=source,
            set_pause=set_pause,
            payment_details=payment_details,
            bill_data=bill_data,
            schedule_details=schedule_details,
            request_options=request_options,
        )
        return _response.data

    async def get_payout_subscription(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetPayoutSubscriptionResponse:
        """
        Retrieves a single payout subscription's details. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetPayoutSubscriptionResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.payout_subscription.get_payout_subscription(
                id=42,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_payout_subscription(id, request_options=request_options)
        return _response.data

    async def update_payout_subscription(
        self,
        id: int,
        *,
        set_pause: typing.Optional[PayoutSetPause] = OMIT,
        payment_details: typing.Optional[PayoutPaymentDetail] = OMIT,
        payment_method: typing.Optional[AuthorizePaymentMethod] = OMIT,
        schedule_details: typing.Optional[PayoutScheduleDetail] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdatePayoutSubscriptionResponse:
        """
        Updates a payout subscription's details. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        set_pause : typing.Optional[PayoutSetPause]

        payment_details : typing.Optional[PayoutPaymentDetail]
            Object describing details of the payout.

        payment_method : typing.Optional[AuthorizePaymentMethod]

        schedule_details : typing.Optional[PayoutScheduleDetail]
            Object describing the schedule for the payout subscription.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        UpdatePayoutSubscriptionResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.payout_subscription.update_payout_subscription(
                id=42,
                set_pause=True,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update_payout_subscription(
            id,
            set_pause=set_pause,
            payment_details=payment_details,
            payment_method=payment_method,
            schedule_details=schedule_details,
            request_options=request_options,
        )
        return _response.data

    async def delete_payout_subscription(
        self, id: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeletePayoutSubscriptionResponse:
        """
        Deletes a payout subscription and prevents future payouts. See [Manage payout subscriptions](/guides/pay-out-developer-payout-subscriptions-manage) for more information.

        Parameters
        ----------
        id : int
            The payout subscription ID.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        DeletePayoutSubscriptionResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.payout_subscription.delete_payout_subscription(
                id=42,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete_payout_subscription(id, request_options=request_options)
        return _response.data
