"""
Balance & Reconciliation API resource.

Endpoints:
    GET  /v1/balance
    GET  /v1/transactions
    POST /v1/transactions/:id/refund
"""

from typing import Any, Dict, Optional

from .session import WaveSession


class BalanceAPI:
    """
    Interact with the Wave Balance & Reconciliation API.

    Allows you to retrieve wallet balance, list transactions,
    and issue refunds.
    """

    def __init__(self, session: WaveSession):
        self._session = session

    def get(self, include_subaccounts: bool = False) -> Dict[str, Any]:
        """
        Retrieve the current balance of your Wave wallet.

        Args:
            include_subaccounts: If True, include subaccount balances in the total.

        Returns:
            Balance object::

                {
                    "amount": "10245",
                    "currency": "XOF"
                }

        Example::

            balance = client.balance.get()
            print(f"Balance: {balance['amount']} {balance['currency']}")
        """
        params = {}
        if include_subaccounts:
            params["include_subaccounts"] = "true"
        return self._session.get("/v1/balance", params=params or None)

    def get_transactions(
        self,
        date: Optional[str] = None,
        after: Optional[str] = None,
        include_subaccounts: bool = False,
        first: Optional[int] = None,
    ) -> Dict[str, Any]:
        """
        Retrieve a paginated list of transactions for a given day.

        Args:
            date: Date in YYYY-MM-DD format. Defaults to today.
            after: Pagination cursor (value of end_cursor from previous response).
            include_subaccounts: If True, include subaccount transactions.
            first: Maximum number of items to retrieve per page.

        Returns:
            Paginated transaction list::

                {
                    "page_info": {"has_next_page": true, "end_cursor": "..."},
                    "date": "2022-11-07",
                    "items": [...]
                }

        Example::

            result = client.balance.get_transactions(date="2024-01-15")
            for tx in result["items"]:
                print(tx["transaction_id"], tx["amount"])
        """
        params: Dict[str, Any] = {}
        if date:
            params["date"] = date
        if after:
            params["after"] = after
        if include_subaccounts:
            params["include_subaccounts"] = "true"
        if first is not None:
            params["first"] = first
        return self._session.get("/v1/transactions", params=params or None)

    def get_all_transactions(
        self,
        date: Optional[str] = None,
        include_subaccounts: bool = False,
    ):
        """
        Retrieve ALL transactions for a given day, automatically handling pagination.

        Args:
            date: Date in YYYY-MM-DD format. Defaults to today.
            include_subaccounts: If True, include subaccount transactions.

        Yields:
            Individual transaction dicts.

        Example::

            for tx in client.balance.get_all_transactions(date="2024-01-15"):
                print(tx["transaction_id"], tx["amount"])
        """
        cursor = None
        while True:
            response = self.get_transactions(
                date=date,
                after=cursor,
                include_subaccounts=include_subaccounts,
            )
            items = response.get("items", [])
            yield from items

            page_info = response.get("page_info", {})
            if not page_info.get("has_next_page"):
                break
            cursor = page_info.get("end_cursor")

    def refund_transaction(self, transaction_id: str) -> None:
        """
        Refund a transaction by its ID.

        Reverses a payment received by your wallet, including fees.
        This operation is idempotent — refunding the same transaction
        twice will not create a duplicate refund.

        Args:
            transaction_id: The Wave transaction ID (e.g., 'T_VZSWJF5MMQ').

        Returns:
            None on success.

        Raises:
            WaveNotFoundError: If the transaction does not exist.
            WaveAPIError: If the refund fails.

        Example::

            client.balance.refund_transaction("T_VZSWJF5MMQ")
        """
        return self._session.post(f"/v1/transactions/{transaction_id}/refund")
