from datetime import date
from typing import Dict, List, Union

from belvo.resources.base import Resource


class Balances(Resource):
    endpoint = "/api/balances/"

    def create(
        self,
        link: str,
        date_from: str,
        *,
        date_to: str = None,
        account: str = None,
        token: str = None,
        save_data: bool = True,
        raise_exception: bool = False,
        **kwargs: Dict,
    ) -> Union[List[Dict], Dict]:
        """Retrieve balances for a link

        Retrieve balances from one or more accounts for a specific link within a specified date range. You must provide a Link and a date range defined by `date_from` and `date_to`.

        Example:
        ```python
        # Fetch balances for a Link
        balances = client.Balances.create(
            "b91835f5-6f83-4d9b-a0ad-a5a249f18b7c",
            "2019-07-01",
            date_to="2019-07-31"
        )

        # Fetch balances for a Link with timeout after 15 seconds
        balances = client.Balances.create(
            "b91835f5-6f83-4d9b-a0ad-a5a249f18b7c",
            "2019-07-01",
            date_to="2019-07-31",    
            timeout=15
        )
        ```

        Args:
            link (str): The `link.id` that you want to get information for (UUID).
            date_from (str): Date from which you want to start receiving balances, in `YYYY-MM-DD` format. The value of `date_from` cannot be greater than `date_to`.
            date_to (str, optional): Date that you want to stop receiving balances, in `YYYY-MM-DD` format. The value of `date_to` cannot be greater than today's date (in other words, no future dates). If you do not provide a `date_to` we automatically set the date to today.
            account (str, optional): If provided, only balances matching this `account.id` are returned (UUID). Defaults to None.
            token (str, optional): The MFA token generated by the bank in order to access the institution. Defaults to None.
            save_data (bool, optional): Indicates whether or not to persist the data in Belvo. Defaults to `True`.
            raise_exception (bool, optional): Indicates whether to raise an exception or return the API error. Defaults to `False`.

        Returns:
            Union[List[Dict], Dict]: For more information on the response from the API, see our [Balances API documentation](https://developers.belvo.com/reference/retrievebalances).
        """

        date_to = date_to or date.today().isoformat()

        data = {"link": link, "date_from": date_from, "date_to": date_to, "save_data": save_data}

        if account:
            data.update(account=account)
        if token:
            data.update(token=token)

        return self.session.post(
            self.endpoint, data=data, raise_exception=raise_exception, **kwargs
        )
