import requests
import xml.etree.ElementTree as ET
from typing import Dict, Any, Optional


class MerchantPaymentService:
    """Merchant payment service for wallet API."""

    def __init__(self, url: str, addon_id: str, country_id: str, api_key: str):
        self.url = url.rstrip('/')
        self.addon_id = addon_id
        self.country_id = country_id
        self.api_key = api_key

    def do_payment(self, data: Dict[str, str]) -> Dict[str, Any]:
        """
        Process a merchant payment.

        Args:
            data: Dict containing currency, mercode, msisdn, amount, pin

        Returns:
            Dict with broker, mapping, wallet responses or error
        """
        required_fields = ['currency', 'mercode', 'msisdn', 'amount', 'pin']
        for field in required_fields:
            if field not in data:
                return {"error": f"Missing field: {field}", "status": 400}

        currency = data['currency'].lower()
        mercode = data['mercode']
        msisdn = data['msisdn']
        amount = data['amount']
        pin = data['pin']

        broker = "broker-usd" if currency == "usd" else "broker-cdf"

        full_url = (
            f"{self.url}/{broker}/v1/wallet/merchantpaymentonestep/"
            f"addon_id/{self.addon_id}/country_id/{self.country_id}/"
            f"currency/{currency}?mercode={mercode}&msisdn2={msisdn}&amount={amount}&pin2={pin}"
        )

        try:
            response = requests.get(
                url=full_url,
                headers={'X-Apiom-Key': self.api_key},
                timeout=30
            )
            response.raise_for_status()
            xml_response = response.text

            root = ET.fromstring(xml_response)

            return {
                "broker_response": self._xml_to_dict(root.find("broker_response")),
                "mapping_response": self._xml_to_dict(root.find("mapping_response")),
                "wallet_response": self._xml_to_dict(root.find("wallet_response")),
            }

        except requests.exceptions.HTTPError as err:
            return {"error": str(err), "status": err.response.status_code}
        except ET.ParseError as err:
            return {"error": f"XML error: {str(err)}", "status": 500}
        except requests.exceptions.RequestException as err:
            return {"error": f"Request error: {str(err)}", "status": 0}

    def _xml_to_dict(self, element) -> Optional[Dict[str, str]]:
        """Convert XML element to dictionary."""
        if element is None:
            return None
        return {child.tag: child.text for child in element if child.text is not None}
