from typing import Any, Dict, List, Optional


class BulkPayments:
    """Create and manage bulk payment batches."""

    def __init__(self, client):
        self._client = client

    def create(
        self,
        label: str = None,
        idempotency_key: str = None,
    ) -> dict:
        """
        Create a new draft bulk payment batch.

        Args:
            label: Optional label for the batch
            idempotency_key: Unique key to prevent duplicate requests

        Returns:
            Dict with batch details (id, status, etc.)
        """
        body = {}
        if label is not None:
            body["label"] = label
        res = self._client.post("/bulk-payments", json=body, idempotency_key=idempotency_key)
        return res["data"]

    def add_items(
        self,
        batch_id: str,
        items: List[Dict[str, Any]],
    ) -> dict:
        """
        Add items to a draft batch.

        Each item should have: walletAddress, amount, and optionally
        recipientName, reference, description.

        Args:
            batch_id: Batch ID
            items: List of payment items

        Returns:
            Updated batch details
        """
        res = self._client.post(f"/bulk-payments/{batch_id}/items", json={"items": items})
        return res["data"]

    def import_file(
        self,
        batch_id: str,
        file_path: str,
    ) -> dict:
        """
        Import items from a CSV or XLSX file.

        Args:
            batch_id: Batch ID
            file_path: Path to the CSV or XLSX file

        Returns:
            Updated batch details with imported items
        """
        res = self._client.post_file(f"/bulk-payments/{batch_id}/import", file_path, "file")
        return res["data"]

    def validate(self, batch_id: str) -> dict:
        """
        Validate a draft batch (calculates fees, checks balance).

        Returns:
            Validated batch details (status will be VALIDATED or PENDING_APPROVAL)
        """
        res = self._client.post(f"/bulk-payments/{batch_id}/validate", json={})
        return res["data"]

    def execute(self, batch_id: str) -> dict:
        """
        Execute a validated batch (reserves funds and starts processing).

        Returns:
            Batch details with status PROCESSING
        """
        res = self._client.post(f"/bulk-payments/{batch_id}/execute", json={})
        return res["data"]

    def retry(self, batch_id: str) -> dict:
        """
        Retry failed items in a batch.

        Returns:
            Updated batch details
        """
        res = self._client.post(f"/bulk-payments/{batch_id}/retry", json={})
        return res["data"]

    def cancel(self, batch_id: str) -> dict:
        """
        Cancel a draft or validated batch.

        Returns:
            Cancelled batch details
        """
        res = self._client.post(f"/bulk-payments/{batch_id}/cancel", json={})
        return res["data"]

    def list(
        self,
        page: int = None,
        limit: int = None,
        status: str = None,
    ) -> dict:
        """
        List bulk payment batches.

        Args:
            page: Page number
            limit: Items per page
            status: Filter by status

        Returns:
            Dict with "items" (list) and "total" (int)
        """
        params = {"page": page, "limit": limit, "status": status}
        res = self._client.get("/bulk-payments", params=params)
        return res["data"]

    def get(self, batch_id: str) -> dict:
        """
        Get batch detail with items.

        Returns:
            Batch details including items list
        """
        res = self._client.get(f"/bulk-payments/{batch_id}")
        return res["data"]

    def export(self, batch_id: str) -> str:
        """
        Export batch items as CSV.

        Returns:
            CSV string
        """
        return self._client.get_raw(f"/bulk-payments/{batch_id}/export")

    def download_template(self, format: str = "csv") -> str:
        """
        Download the bulk payment template file.

        Args:
            format: "csv" or "xlsx" (default: "csv")

        Returns:
            Template file content as string
        """
        return self._client.get_raw("/bulk-payments/template", params={"format": format})
