"""
Send payment confirmation email function.
"""

import asyncio
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, To

from apexsaas.exceptions import ApexEmailError, ApexValidationError
from apexsaas.email._templates import get_payment_confirmation_template


async def send_payment_confirmation(
    to_email: str,
    to_name: str,
    amount: str,
    currency: str,
    transaction_id: str,
    sendgrid_api_key: str,
    from_email: str,
    from_name: str = "Apex",
    receipt_url: str = None
) -> dict:
    """
    Send payment confirmation email (async).
    
    Args:
        to_email: Recipient email address
        to_name: Recipient name
        amount: Payment amount
        currency: Currency code (e.g., "USD")
        transaction_id: Transaction/order ID
        sendgrid_api_key: SendGrid API key
        from_email: Sender email address
        from_name: Sender name (default: "Apex")
        receipt_url: Optional receipt URL
    
    Returns:
        dict with success status and message details
    
    Raises:
        ApexValidationError: If required parameters are missing
        ApexEmailError: If SendGrid API call fails
    """
    if not to_email or not to_name:
        raise ApexValidationError("to_email and to_name are required")
    if not amount or not currency:
        raise ApexValidationError("amount and currency are required")
    if not transaction_id:
        raise ApexValidationError("transaction_id is required")
    if not sendgrid_api_key:
        raise ApexValidationError("sendgrid_api_key is required")
    if not from_email:
        raise ApexValidationError("from_email is required")
    
    try:
        # Get HTML template
        html_content = get_payment_confirmation_template(
            to_name, amount, currency, transaction_id, receipt_url or None
        )
        
        # Create message
        message = Mail(
            from_email=(from_email, from_name),
            to_emails=To(to_email),
            subject=f"Payment Confirmation - {amount} {currency}",
            html_content=html_content,
            plain_text_content=f"Payment of {amount} {currency} confirmed. Transaction ID: {transaction_id}"
        )
        
        # Send email (run in thread to avoid blocking)
        def _send():
            client = SendGridAPIClient(api_key=sendgrid_api_key)
            return client.send(message)
        
        response = await asyncio.to_thread(_send)
        
        # Check response
        if response.status_code not in [200, 201, 202]:
            error_msg = f"SendGrid API error: {response.status_code}"
            # Try to extract error message from response body
            try:
                if hasattr(response, 'body') and response.body:
                    import json
                    error_data = json.loads(response.body)
                    if 'errors' in error_data and len(error_data['errors']) > 0:
                        error_msg = error_data['errors'][0].get('message', error_msg)
            except:
                pass
            return {
                'success': False,
                'message': error_msg,
                'status_code': response.status_code
            }
        
        return {
            'success': True,
            'message_id': response.headers.get('X-Message-Id', 'unknown'),
            'message': f'Payment confirmation email sent successfully to {to_email}'
        }
    
    except Exception as e:
        if isinstance(e, (ApexValidationError, ApexEmailError)):
            raise
        
        # Extract error message from SendGrid exception
        error_msg = str(e)
        if hasattr(e, 'body'):
            try:
                import json
                error_data = json.loads(e.body)
                if 'errors' in error_data and len(error_data['errors']) > 0:
                    error_msg = error_data['errors'][0].get('message', error_msg)
            except:
                pass
        
        # Return error dict instead of raising exception
        return {
            'success': False,
            'message': f'Failed to send payment confirmation email: {error_msg}',
            'error': error_msg
        }


def send_payment_confirmation_sync(
    to_email: str,
    to_name: str,
    amount: str,
    currency: str,
    transaction_id: str,
    sendgrid_api_key: str,
    from_email: str,
    from_name: str = "Apex",
    receipt_url: str = None
) -> dict:
    """Sync wrapper for send_payment_confirmation."""
    from apexsaas.core.utils.async_runner import run_async
    try:
        result = run_async(send_payment_confirmation(
            to_email=to_email,
            to_name=to_name,
            amount=amount,
            currency=currency,
            transaction_id=transaction_id,
            sendgrid_api_key=sendgrid_api_key,
            from_email=from_email,
            from_name=from_name,
            receipt_url=receipt_url
        ))
        return result
    except Exception as e:
        error_msg = str(e)
        if hasattr(e, 'body'):
            try:
                import json
                error_data = json.loads(e.body)
                if 'errors' in error_data and len(error_data['errors']) > 0:
                    error_msg = error_data['errors'][0].get('message', error_msg)
            except:
                pass
        return {
            'success': False,
            'message': f'Failed to send payment confirmation email: {error_msg}',
            'error': error_msg
        }
