from __future__ import annotations

import logging
from typing import Any

from spherepay_mcp.domain.value_objects import ApiError, ErrorCategory
from spherepay_mcp.ports.spherepay_gateway import SpherePayGateway

logger = logging.getLogger(__name__)


class FundingInstrumentService:
    """Orchestrates creation of bank accounts and wallets."""

    def __init__(self, gateway: SpherePayGateway):
        self._gw = gateway

    async def setup_funding(
        self,
        customer_id: str,
        instrument_type: str,
        *,
        # Bank account fields
        bank_name: str | None = None,
        account_name: str | None = None,
        currency: str | None = None,
        account_details: dict[str, Any] | None = None,
        account_owner: dict[str, Any] | None = None,
        networks: list[str] | None = None,
        # Wallet fields
        address: str | None = None,
        network: str | None = None,
    ) -> dict[str, Any]:
        """Create a bank account or wallet for a customer.

        instrument_type must be 'bank_account' or 'wallet'.
        """
        if instrument_type == "bank_account":
            if not all([bank_name, account_name, currency, account_details, account_owner]):
                raise ApiError(
                    category=ErrorCategory.VALIDATION,
                    message="Bank account requires: bank_name, account_name, currency, account_details, account_owner",
                    status_code=400,
                )
            payload: dict[str, Any] = {
                "customerId": customer_id,
                "bankName": bank_name,
                "accountName": account_name,
                "currency": currency,
                "accountDetails": account_details,
                "accountOwner": account_owner,
            }
            if networks:
                payload["networks"] = networks
            result = await self._gw.create_bank_account(payload)
            return {
                "instrument_type": "bank_account",
                "data": result.get("data", result),
            }

        elif instrument_type == "wallet":
            if not all([address, network]):
                raise ApiError(
                    category=ErrorCategory.VALIDATION,
                    message="Wallet requires: address, network",
                    status_code=400,
                )
            payload = {
                "customerId": customer_id,
                "address": address,
                "network": network,
            }
            result = await self._gw.create_wallet(payload)
            return {
                "instrument_type": "wallet",
                "data": result.get("data", result),
            }

        else:
            raise ApiError(
                category=ErrorCategory.VALIDATION,
                message=f"Invalid instrument_type: {instrument_type}. Must be 'bank_account' or 'wallet'.",
                status_code=400,
            )
