"""Stripe Connect endpoints mixin."""

from typing import TYPE_CHECKING

from growflow_billing.models.connect import (
    ConnectAccount,
    ConnectAccountLink,
    ConnectAccountsPage,
    ConnectBalance,
    ConnectLoginLink,
    ConnectTransfer,
    ConnectTransfersPage,
)

if TYPE_CHECKING:
    from growflow_billing.client import GrowFlowBillingClient


class ConnectMixin:
    """Mixin providing Stripe Connect account and transfer operations."""

    async def list_connect_accounts(
        self: "GrowFlowBillingClient",
        limit: int = 100,
        starting_after: str | None = None,
    ) -> ConnectAccountsPage:
        """List all Stripe Connect accounts.

        Args:
            limit: Maximum number of accounts to return (default: 100)
            starting_after: Cursor for pagination (account ID)

        Returns:
            ConnectAccountsPage with accounts and pagination info
        """
        params: dict[str, str | int] = {"limit": limit}
        if starting_after:
            params["starting_after"] = starting_after

        response = await self._request("GET", "/admin/accounts", params=params)

        if isinstance(response, list):
            return ConnectAccountsPage(data=[ConnectAccount(**a) for a in response])
        return ConnectAccountsPage(
            data=[ConnectAccount(**a) for a in response.get("data", [])],
            has_more=response.get("has_more", False),
        )

    async def get_connect_account(
        self: "GrowFlowBillingClient",
        account_id: str,
    ) -> ConnectAccount:
        """Get a single Stripe Connect account by ID.

        Args:
            account_id: Stripe account ID (acct_xxx)

        Returns:
            ConnectAccount object

        Raises:
            NotFoundError: If account not found
        """
        response = await self._request("GET", f"/admin/accounts/{account_id}")
        return ConnectAccount(**response)

    async def create_connect_account(
        self: "GrowFlowBillingClient",
        email: str,
        country: str = "IT",
        business_type: str = "individual",
        metadata: dict[str, str] | None = None,
    ) -> ConnectAccount:
        """Create a Stripe Express Connect account.

        Args:
            email: Account holder email
            country: Two-letter country code (default: IT)
            business_type: Account type (individual or company)
            metadata: Additional metadata key-value pairs

        Returns:
            Created ConnectAccount object
        """
        payload: dict[str, str | dict[str, str]] = {
            "email": email,
            "country": country,
            "business_type": business_type,
        }
        if metadata:
            payload["metadata"] = metadata

        response = await self._request("POST", "/admin/accounts", json=payload)
        return ConnectAccount(**response)

    async def create_onboarding_link(
        self: "GrowFlowBillingClient",
        account_id: str,
        refresh_url: str,
        return_url: str,
    ) -> ConnectAccountLink:
        """Generate an Account Link for Connect onboarding.

        Args:
            account_id: Stripe account ID (acct_xxx)
            refresh_url: URL to redirect if the link expires
            return_url: URL to redirect after onboarding completes

        Returns:
            ConnectAccountLink with onboarding URL
        """
        response = await self._request(
            "POST",
            f"/admin/accounts/{account_id}/onboarding-link",
            json={"refresh_url": refresh_url, "return_url": return_url},
        )
        return ConnectAccountLink(**response)

    async def create_login_link(
        self: "GrowFlowBillingClient",
        account_id: str,
    ) -> ConnectLoginLink:
        """Generate a login link for the Stripe Express dashboard.

        Args:
            account_id: Stripe account ID (acct_xxx)

        Returns:
            ConnectLoginLink with dashboard URL
        """
        response = await self._request(
            "POST",
            f"/admin/accounts/{account_id}/login-link",
        )
        return ConnectLoginLink(**response)

    async def get_connect_account_balance(
        self: "GrowFlowBillingClient",
        account_id: str,
    ) -> ConnectBalance:
        """Get available and pending balance for a Connect account.

        Args:
            account_id: Stripe account ID (acct_xxx)

        Returns:
            ConnectBalance with available and pending amounts
        """
        response = await self._request(
            "GET",
            f"/admin/accounts/{account_id}/balance",
        )
        return ConnectBalance(**response)

    async def create_transfer(
        self: "GrowFlowBillingClient",
        account_id: str,
        amount_cents: int,
        currency: str = "eur",
        description: str | None = None,
        metadata: dict[str, str] | None = None,
    ) -> ConnectTransfer:
        """Transfer funds to a Connect account.

        Args:
            account_id: Destination Stripe account ID (acct_xxx)
            amount_cents: Transfer amount in cents (must be > 0)
            currency: Three-letter currency code (default: eur)
            description: Optional transfer description
            metadata: Additional metadata key-value pairs

        Returns:
            ConnectTransfer object

        Raises:
            ValidationError: If amount_cents <= 0
        """
        payload: dict[str, str | int | dict[str, str]] = {
            "amount": amount_cents,
            "currency": currency,
        }
        if description:
            payload["description"] = description
        if metadata:
            payload["metadata"] = metadata

        response = await self._request(
            "POST",
            f"/admin/accounts/{account_id}/transfers",
            json=payload,
        )
        return ConnectTransfer(**response)

    async def list_transfers(
        self: "GrowFlowBillingClient",
        account_id: str,
        limit: int = 100,
        starting_after: str | None = None,
    ) -> ConnectTransfersPage:
        """List transfers for a Connect account.

        Args:
            account_id: Stripe account ID (acct_xxx)
            limit: Maximum number of transfers to return (default: 100)
            starting_after: Cursor for pagination (transfer ID)

        Returns:
            ConnectTransfersPage with transfers and pagination info
        """
        params: dict[str, str | int] = {"limit": limit}
        if starting_after:
            params["starting_after"] = starting_after

        response = await self._request(
            "GET",
            f"/admin/accounts/{account_id}/transfers",
            params=params,
        )

        if isinstance(response, list):
            return ConnectTransfersPage(data=[ConnectTransfer(**t) for t in response])
        return ConnectTransfersPage(
            data=[ConnectTransfer(**t) for t in response.get("data", [])],
            has_more=response.get("has_more", False),
        )
