"""
Create PayPal order function - standalone.
"""

import asyncio
from typing import Dict, Any, Optional

from apexsaas.infrastructure.paypal.client import PayPalClient
from apexsaas.infrastructure.paypal.service import PayPalService
from apexsaas.exceptions import ApexValidationError, ApexPaymentError


async def create_order(
    amount: str,
    currency: str = "USD",
    client_id: str = None,
    client_secret: str = None,
    return_url: str = None,
    cancel_url: str = None,
    description: str = None,
    sandbox: bool = True
) -> Dict[str, Any]:
    """
    Create a PayPal order (async).
    
    Args:
        amount: Order amount (as string, e.g., "99.99")
        currency: Currency code (default: "USD")
        client_id: PayPal client ID
        client_secret: PayPal client secret
        return_url: URL to redirect after approval
        cancel_url: URL to redirect if cancelled
        description: Order description
        sandbox: Use sandbox mode (default: True)
    
    Returns:
        dict with order data:
        {
            'order_id': str,
            'status': str,
            'amount': str,
            'currency': str,
            'approval_url': str
        }
    
    Raises:
        ApexValidationError: If input validation fails
        ApexPaymentError: If PayPal API call fails
    
    Example:
        ```python
        # Async usage
        order = await create_order(
            amount="99.99",
            currency="USD",
            client_id="...",
            client_secret="...",
            sandbox=True
        )
        
        # Sync usage (use create_order_sync)
        from apexsaas.payments import create_order_sync
        order = create_order_sync(...)
        ```
    """
    if not amount:
        raise ApexValidationError("amount is required")
    try:
        float(amount)
    except (ValueError, TypeError):
        raise ApexValidationError("amount must be a valid number")
    
    if float(amount) <= 0:
        raise ApexValidationError("amount must be greater than 0")
    
    if not currency or len(currency) != 3:
        raise ApexValidationError("currency must be a 3-letter code (e.g., USD)")
    
    # Get credentials from environment if not provided
    import os
    client_id = client_id or os.getenv("PAYPAL_CLIENT_ID")
    client_secret = client_secret or os.getenv("PAYPAL_CLIENT_SECRET")
    
    if not client_id or not client_secret:
        raise ApexValidationError("PayPal credentials required (client_id and client_secret)")
    
    client = PayPalClient(
        client_id=client_id,
        client_secret=client_secret,
        mode="sandbox" if sandbox else "live"
    )
    service = PayPalService(client=client)
    
    purchase_units = [{
        "amount": {
            "currency_code": currency.upper(),
            "value": str(amount)
        },
        "description": description or f"Payment of {amount} {currency}"
    }]
    
    result = await service.create_order(
        intent="CAPTURE",
        purchase_units=purchase_units,
        return_url=return_url,
        cancel_url=cancel_url
    )
    
    # Extract approval URL
    approval_url = None
    for link in result.get("links", []):
        if link.get("rel") == "approve":
            approval_url = link.get("href")
            break
    
    return {
        'order_id': result.get('id'),
        'status': result.get('status'),
        'amount': amount,
        'currency': currency.upper(),
        'approval_url': approval_url
    }


def create_order_sync(
    amount: str,
    currency: str = "USD",
    client_id: str = None,
    client_secret: str = None,
    return_url: str = None,
    cancel_url: str = None,
    description: str = None,
    sandbox: bool = True
) -> Dict[str, Any]:
    """
    Create a PayPal order (sync wrapper).
    
    This is a synchronous wrapper for the async create_order function.
    Use this in non-async contexts.
    
    Args:
        Same as create_order()
    
    Returns:
        Same as create_order()
    
    Example:
        ```python
        from apexsaas.payments import create_order_sync
        
        order = create_order_sync(
            amount="99.99",
            currency="USD",
            client_id="...",
            client_secret="...",
            sandbox=True
        )
        ```
    """
    from apexsaas.core.utils.async_runner import run_async
    try:
        return run_async(create_order(
            amount=amount,
            currency=currency,
            client_id=client_id,
            client_secret=client_secret,
            return_url=return_url,
            cancel_url=cancel_url,
            description=description,
            sandbox=sandbox
        ))
    except Exception as e:
        raise ApexPaymentError(f"Failed to create order: {str(e)}")


