"""
Create PayPal subscription function - standalone.
"""

import asyncio
from typing import Dict, Any

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


async def create_subscription(
    plan_id: str,
    subscriber: Dict[str, Any],
    return_url: str,
    cancel_url: str,
    client_id: str = None,
    client_secret: str = None,
    sandbox: bool = True
) -> Dict[str, Any]:
    """
    Create a PayPal subscription (async).
    
    Args:
        plan_id: Billing plan ID
        subscriber: Subscriber information
        return_url: URL to redirect after approval
        cancel_url: URL to redirect if cancelled
        client_id: PayPal client ID
        client_secret: PayPal client secret
        sandbox: Use sandbox mode (default: True)
    
    Returns:
        dict with subscription data and approval links
    
    Raises:
        ApexValidationError: If input validation fails
        ApexPaymentError: If PayPal API call fails
    """
    if not plan_id:
        raise ApexValidationError("plan_id is required")
    if not subscriber:
        raise ApexValidationError("subscriber is required")
    if not return_url:
        raise ApexValidationError("return_url is required")
    if not cancel_url:
        raise ApexValidationError("cancel_url is required")
    
    # 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)
    
    result = await service.create_subscription(
        plan_id=plan_id,
        subscriber=subscriber,
        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 {
        **result,
        'approval_url': approval_url
    }


def create_subscription_sync(
    plan_id: str,
    subscriber: Dict[str, Any],
    return_url: str,
    cancel_url: str,
    client_id: str = None,
    client_secret: str = None,
    sandbox: bool = True
) -> Dict[str, Any]:
    """Sync wrapper for create_subscription."""
    from apexsaas.core.utils.async_runner import run_async
    try:
        return run_async(create_subscription(
            plan_id=plan_id,
            subscriber=subscriber,
            return_url=return_url,
            cancel_url=cancel_url,
            client_id=client_id,
            client_secret=client_secret,
            sandbox=sandbox
        ))
    except Exception as e:
        raise ApexPaymentError(f"Failed to create subscription: {str(e)}")
