"""Zelle payment integration via J.P. Morgan Payments API."""

import time
import httpx
from typing import Dict, Any, Optional
from agenticlypay.config import config


class ZelleManager:
    """Manages Zelle payments via J.P. Morgan Payments API."""

    def __init__(self):
        """Initialize the Zelle manager."""
        self.client_id = config.jpmorgan_client_id
        self.client_secret = config.jpmorgan_client_secret
        self.token_url = config.jpmorgan_token_url
        self.api_base_url = config.jpmorgan_api_base_url
        self._access_token: Optional[str] = None
        self._token_expires_at: Optional[float] = None

    def _get_access_token(self) -> str:
        """
        Get or refresh OAuth2 access token.
        
        Returns:
            Access token string
        """
        # Return cached token if still valid (with 5 minute buffer)
        if self._access_token and self._token_expires_at:
            if time.time() < (self._token_expires_at - 300):
                return self._access_token

        if not self.client_id or not self.client_secret:
            raise ValueError("J.P. Morgan API credentials not configured")

        # Request new token
        with httpx.Client() as client:
            response = client.post(
                self.token_url,
                data={
                    "grant_type": "client_credentials",
                    "client_id": self.client_id,
                    "client_secret": self.client_secret,
                },
                headers={"Content-Type": "application/x-www-form-urlencoded"},
            )

            if response.status_code != 200:
                raise Exception(f"Failed to get access token: {response.status_code} {response.text}")

            token_data = response.json()
        self._access_token = token_data["access_token"]
        expires_in = token_data.get("expires_in", 3600)
        self._token_expires_at = time.time() + expires_in

        return self._access_token

    def send_zelle_payment(
        self,
        email: str,
        amount: int,  # Amount in cents
        reference: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        Send a Zelle payment to an email address.
        
        Args:
            email: Recipient email address (must be Zelle-compatible)
            amount: Amount in cents (e.g., 10000 for $100.00)
            reference: Optional payment reference/description
            
        Returns:
            Dictionary with payment status
        """
        access_token = self._get_access_token()
        
        # Convert cents to dollars for Zelle API
        amount_dollars = amount / 100.0
        
        # Prepare payment request
        payment_data = {
            "recipient_email": email,
            "amount": amount_dollars,
            "currency": "USD",
        }
        
        if reference:
            payment_data["reference"] = reference

        # Make API call to send Zelle payment
        # Note: Actual endpoint may vary based on J.P. Morgan API documentation
        with httpx.Client() as client:
            response = client.post(
                f"{self.api_base_url}/v1/payments/zelle",
                json=payment_data,
                headers={
                    "Authorization": f"Bearer {access_token}",
                    "Content-Type": "application/json",
                },
            )

            if response.status_code != 200:
                raise Exception(f"Failed to send Zelle payment: {response.status_code} {response.text}")

            result = response.json()
        
        return {
            "success": True,
            "payment_id": result.get("payment_id"),
            "email": email,
            "amount": amount,
            "amount_dollars": amount_dollars,
            "status": result.get("status", "pending"),
            "reference": reference,
            "timestamp": time.time(),
        }

    def get_payment_status(self, payment_id: str) -> Dict[str, Any]:
        """
        Get the status of a Zelle payment.
        
        Args:
            payment_id: Payment ID from send_zelle_payment
            
        Returns:
            Dictionary with payment status
        """
        access_token = self._get_access_token()
        
        with httpx.Client() as client:
            response = client.get(
                f"{self.api_base_url}/v1/payments/{payment_id}",
                headers={
                    "Authorization": f"Bearer {access_token}",
                },
            )

            if response.status_code != 200:
                raise Exception(f"Failed to get payment status: {response.status_code} {response.text}")

            return response.json()

