import requests
import json
import sqlite3
from datetime import datetime, timedelta
import uuid
import os
import logging
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from auth import get_db_connection
from dotenv import load_dotenv

# PayPal API Configuration - Remove default values for production
PAYPAL_CLIENT_ID = os.getenv("PAYPAL_CLIENT_ID")
PAYPAL_SECRET = os.getenv("PAYPAL_SECRET")
PAYPAL_BASE_URL = os.getenv("PAYPAL_BASE_URL", "https://api-m.sandbox.paypal.com")

# Add validation to ensure credentials are provided
# Set up logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(os.path.join(os.path.dirname(__file__), "../logs/paypal.log")),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger("paypal_integration")

# Then replace print statements with logger calls
# For example:
if not PAYPAL_CLIENT_ID or not PAYPAL_SECRET:
    logger.warning("PayPal credentials not found in environment variables")


# Get PayPal access token
# Add better error handling for production
# Create a session with retry capability
def create_retry_session(retries=3, backoff_factor=0.3):
    session = requests.Session()
    retry = Retry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=backoff_factor,
        status_forcelist=[500, 502, 503, 504],
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session

# Then use this session for API calls
# Replace get_access_token with logger instead of print
def get_access_token():
    url = f"{PAYPAL_BASE_URL}/v1/oauth2/token"
    headers = {
        "Accept": "application/json",
        "Accept-Language": "en_US"
    }
    data = "grant_type=client_credentials"
    
    try:
        session = create_retry_session()
        response = session.post(
            url, 
            auth=(PAYPAL_CLIENT_ID, PAYPAL_SECRET),
            headers=headers,
            data=data
        )
        
        if response.status_code == 200:
            return response.json()["access_token"]
        else:
            logger.error(f"Error getting access token: {response.status_code}")
            return None
    except Exception as e:
        logger.error(f"Exception in get_access_token: {str(e)}")
        return None

def call_paypal_api(endpoint, method="GET", data=None, token=None):
    """
    Helper function to make PayPal API calls
    
    Args:
        endpoint: API endpoint (without base URL)
        method: HTTP method (GET, POST, etc.)
        data: Request payload (for POST/PUT)
        token: PayPal access token (will be fetched if None)
        
    Returns:
        tuple: (success, response_data or error_message)
    """
    try:
        if not token:
            token = get_access_token()
            if not token:
                return False, "Failed to get PayPal access token"
        
        url = f"{PAYPAL_BASE_URL}{endpoint}"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {token}"
        }
        
        session = create_retry_session()
        
        if method.upper() == "GET":
            response = session.get(url, headers=headers)
        elif method.upper() == "POST":
            response = session.post(url, headers=headers, data=json.dumps(data) if data else None)
        elif method.upper() == "PUT":
            response = session.put(url, headers=headers, data=json.dumps(data) if data else None)
        else:
            return False, f"Unsupported HTTP method: {method}"
        
        if response.status_code in [200, 201, 204]:
            if response.status_code == 204:  # No content
                return True, {}
            return True, response.json() if response.text else {}
        else:
            logger.error(f"PayPal API error: {response.status_code} - {response.text}")
            return False, f"PayPal API error: {response.status_code} - {response.text}"
            
    except Exception as e:
        logger.error(f"Error calling PayPal API: {str(e)}")
        return False, f"Error calling PayPal API: {str(e)}"

def create_paypal_subscription(user_id, tier):
    """Create a PayPal subscription for a user"""
    try:
        # Get the price from the subscription tier
        from auth import SUBSCRIPTION_TIERS
        
        if tier not in SUBSCRIPTION_TIERS:
            return False, f"Invalid tier: {tier}"
        
        price = SUBSCRIPTION_TIERS[tier]["price"]
        currency = SUBSCRIPTION_TIERS[tier]["currency"]
        
        # Create a PayPal subscription (implement PayPal API calls here)
        # For now, just return a success response
        return True, {
            "subscription_id": f"test_sub_{uuid.uuid4()}",
            "status": "ACTIVE",
            "tier": tier,
            "price": price,
            "currency": currency
        }
    except Exception as e:
        logger.error(f"Error creating PayPal subscription: {str(e)}")
        return False, f"Failed to create PayPal subscription: {str(e)}"

        
# Create a product in PayPal
def create_product(name, description):
    """Create a product in PayPal"""
    payload = {
        "name": name,
        "description": description,
        "type": "SERVICE",
        "category": "SOFTWARE"
    }
    
    success, result = call_paypal_api("/v1/catalogs/products", "POST", payload)
    if success:
        return result["id"]
    else:
        logger.error(f"Failed to create product: {result}")
        return None

# Create a subscription plan in PayPal
# Update create_plan to use INR instead of USD
def create_plan(product_id, name, price, interval="MONTH", interval_count=1):
    """Create a subscription plan in PayPal"""
    payload = {
        "product_id": product_id,
        "name": name,
        "billing_cycles": [
            {
                "frequency": {
                    "interval_unit": interval,
                    "interval_count": interval_count
                },
                "tenure_type": "REGULAR",
                "sequence": 1,
                "total_cycles": 0,  # Infinite cycles
                "pricing_scheme": {
                    "fixed_price": {
                        "value": str(price),
                        "currency_code": "USD"
                    }
                }
            }
        ],
        "payment_preferences": {
            "auto_bill_outstanding": True,
            "setup_fee": {
                "value": "0",
                "currency_code": "USD"
            },
            "setup_fee_failure_action": "CONTINUE",
            "payment_failure_threshold": 3
        }
    }
    
    success, result = call_paypal_api("/v1/billing/plans", "POST", payload)
    if success:
        return result["id"]
    else:
        logger.error(f"Failed to create plan: {result}")
        return None

# Update initialize_subscription_plans to use INR pricing
def initialize_subscription_plans():
    """
    Initialize PayPal subscription plans for the application.
    This should be called once to set up the plans in PayPal.
    """
    try:
        # Check if plans already exist
        existing_plans = get_subscription_plans()
        if existing_plans and len(existing_plans) >= 2:
            logger.info("PayPal plans already initialized")
            return existing_plans
        
        # First, create products for each tier
        products = {
            "standard_tier": {
                "name": "Standard Legal Document Analysis",
                "description": "Standard subscription with document analysis features",
                "type": "SERVICE",
                "category": "SOFTWARE"
            },
            "premium_tier": {
                "name": "Premium Legal Document Analysis",
                "description": "Premium subscription with all document analysis features",
                "type": "SERVICE",
                "category": "SOFTWARE"
            }
        }
        
        product_ids = {}
        for tier, product_data in products.items():
            success, result = call_paypal_api("/v1/catalogs/products", "POST", product_data)
            if success:
                product_ids[tier] = result["id"]
                logger.info(f"Created PayPal product for {tier}: {result['id']}")
            else:
                logger.error(f"Failed to create product for {tier}: {result}")
                return None
        
        # Define the plans with product IDs - Changed currency to USD
        plans = {
            "standard_tier": {
                "product_id": product_ids["standard_tier"],
                "name": "Standard Plan",
                "description": "Standard subscription with basic features",
                "billing_cycles": [
                    {
                        "frequency": {
                            "interval_unit": "MONTH",
                            "interval_count": 1
                        },
                        "tenure_type": "REGULAR",
                        "sequence": 1,
                        "total_cycles": 0,
                        "pricing_scheme": {
                            "fixed_price": {
                                "value": "9.99",
                                "currency_code": "USD"
                            }
                        }
                    }
                ],
                "payment_preferences": {
                    "auto_bill_outstanding": True,
                    "setup_fee": {
                        "value": "0",
                        "currency_code": "USD"
                    },
                    "setup_fee_failure_action": "CONTINUE",
                    "payment_failure_threshold": 3
                }
            },
            "premium_tier": {
                "product_id": product_ids["premium_tier"],
                "name": "Premium Plan",
                "description": "Premium subscription with all features",
                "billing_cycles": [
                    {
                        "frequency": {
                            "interval_unit": "MONTH",
                            "interval_count": 1
                        },
                        "tenure_type": "REGULAR",
                        "sequence": 1,
                        "total_cycles": 0,
                        "pricing_scheme": {
                            "fixed_price": {
                                "value": "19.99",
                                "currency_code": "USD"
                            }
                        }
                    }
                ],
                "payment_preferences": {
                    "auto_bill_outstanding": True,
                    "setup_fee": {
                        "value": "0",
                        "currency_code": "USD"
                    },
                    "setup_fee_failure_action": "CONTINUE",
                    "payment_failure_threshold": 3
                }
            }
        }
        
        # Create the plans in PayPal
        created_plans = {}
        for tier, plan_data in plans.items():
            success, result = call_paypal_api("/v1/billing/plans", "POST", plan_data)
            if success:
                created_plans[tier] = result["id"]
                logger.info(f"Created PayPal plan for {tier}: {result['id']}")
            else:
                logger.error(f"Failed to create plan for {tier}: {result}")
        
        # Save the plan IDs to a file
        if created_plans:
            save_subscription_plans(created_plans)
            return created_plans
        else:
            logger.error("Failed to create any PayPal plans")
            return None
    except Exception as e:
        logger.error(f"Error initializing subscription plans: {str(e)}")
        return None

# Update create_subscription_link to use call_paypal_api helper
def create_subscription_link(plan_id):
    # Get the plan IDs
    plans = get_subscription_plans()
    if not plans:
        return None
    
    # Use environment variable for the app URL to make it work in different environments
    app_url = os.getenv("APP_URL", "http://localhost:8501")
    
    payload = {
        "plan_id": plans[plan_id],
        "application_context": {
            "brand_name": "Legal Document Analyzer",
            "locale": "en_US",
            "shipping_preference": "NO_SHIPPING",
            "user_action": "SUBSCRIBE_NOW",
            "return_url": f"{app_url}?status=success&subscription_id={{id}}",
            "cancel_url": f"{app_url}?status=cancel"
        }
    }
    
    success, data = call_paypal_api("/v1/billing/subscriptions", "POST", payload)
    if not success:
        logger.error(f"Error creating subscription: {data}")
        return None
    
    try:
        return {
            "subscription_id": data["id"],
            "approval_url": next(link["href"] for link in data["links"] if link["rel"] == "approve")
        }
    except Exception as e:
        logger.error(f"Exception processing subscription response: {str(e)}")
        return None

# Fix the webhook handler function signature to match how it's called in app.py
def handle_subscription_webhook(payload):
    """
    Handle PayPal subscription webhooks
    
    Args:
        payload: The full webhook payload
        
    Returns:
        tuple: (success, result)
            - success: True if successful, False otherwise
            - result: Success message or error message
    """
    try:
        event_type = payload.get("event_type")
        resource = payload.get("resource", {})
        
        logger.info(f"Received PayPal webhook: {event_type}")
        
        # Handle different event types
        if event_type == "BILLING.SUBSCRIPTION.CREATED":
            # A subscription was created
            subscription_id = resource.get("id")
            if not subscription_id:
                return False, "Missing subscription ID in webhook"
                
            # Update subscription status in database
            conn = get_db_connection()
            cursor = conn.cursor()
            cursor.execute(
                "UPDATE subscriptions SET status = 'pending' WHERE paypal_subscription_id = ?",
                (subscription_id,)
            )
            conn.commit()
            conn.close()
            
            return True, "Subscription created successfully"
            
        elif event_type == "BILLING.SUBSCRIPTION.ACTIVATED":
            # A subscription was activated
            subscription_id = resource.get("id")
            if not subscription_id:
                return False, "Missing subscription ID in webhook"
                
            # Update subscription status in database
            conn = get_db_connection()
            cursor = conn.cursor()
            cursor.execute(
                "UPDATE subscriptions SET status = 'active' WHERE paypal_subscription_id = ?",
                (subscription_id,)
            )
            conn.commit()
            conn.close()
            
            return True, "Subscription activated successfully"
            
        elif event_type == "BILLING.SUBSCRIPTION.CANCELLED":
            # A subscription was cancelled
            subscription_id = resource.get("id")
            if not subscription_id:
                return False, "Missing subscription ID in webhook"
                
            # Update subscription status in database
            conn = get_db_connection()
            cursor = conn.cursor()
            cursor.execute(
                "UPDATE subscriptions SET status = 'cancelled' WHERE paypal_subscription_id = ?",
                (subscription_id,)
            )
            conn.commit()
            conn.close()
            
            return True, "Subscription cancelled successfully"
            
        elif event_type == "BILLING.SUBSCRIPTION.SUSPENDED":
            # A subscription was suspended
            subscription_id = resource.get("id")
            if not subscription_id:
                return False, "Missing subscription ID in webhook"
                
            # Update subscription status in database
            conn = get_db_connection()
            cursor = conn.cursor()
            cursor.execute(
                "UPDATE subscriptions SET status = 'suspended' WHERE paypal_subscription_id = ?",
                (subscription_id,)
            )
            conn.commit()
            conn.close()
            
            return True, "Subscription suspended successfully"
            
        else:
            # Unhandled event type
            logger.info(f"Unhandled webhook event type: {event_type}")
            return True, f"Unhandled event type: {event_type}"
            
    except Exception as e:
        logger.error(f"Error handling webhook: {str(e)}")
        return False, f"Error handling webhook: {str(e)}"
# Add this function to update user subscription
def update_user_subscription(user_email, subscription_id, tier):
    """
    Update a user's subscription status
    
    Args:
        user_email: The email of the user
        subscription_id: The PayPal subscription ID
        tier: The subscription tier
        
    Returns:
        tuple: (success, result)
            - success: True if successful, False otherwise
            - result: Success message or error message
    """
    try:
        # Get user ID from email
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT id FROM users WHERE email = ?", (user_email,))
        user_result = cursor.fetchone()
        
        if not user_result:
            conn.close()
            return False, f"User not found: {user_email}"
        
        user_id = user_result[0]
        
        # Update the subscription status
        cursor.execute(
            "UPDATE subscriptions SET status = 'active' WHERE user_id = ? AND paypal_subscription_id = ?",
            (user_id, subscription_id)
        )
        
        # Deactivate any other active subscriptions for this user
        cursor.execute(
            "UPDATE subscriptions SET status = 'inactive' WHERE user_id = ? AND paypal_subscription_id != ? AND status = 'active'",
            (user_id, subscription_id)
        )
        
        # Update the user's subscription tier
        cursor.execute(
            "UPDATE users SET subscription_tier = ? WHERE email = ?",
            (tier, user_email)
        )
        
        conn.commit()
        conn.close()
        
        return True, f"Subscription updated to {tier} tier"
        
    except Exception as e:
        logger.error(f"Error updating user subscription: {str(e)}")
        return False, f"Error updating subscription: {str(e)}"

# Add this near the top with other path definitions
# Update the PLAN_IDS_PATH definition to use the correct path
PLAN_IDS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "data", "plan_ids.json"))

# Make sure the data directory exists
os.makedirs(os.path.dirname(PLAN_IDS_PATH), exist_ok=True)

# Add this debug log to see where the file is expected
logger.info(f"PayPal plans will be stored at: {PLAN_IDS_PATH}")

# Add this function if it's not defined elsewhere
def get_db_connection():
    """Get a connection to the SQLite database"""
    DB_PATH = os.getenv("DB_PATH", os.path.join(os.path.dirname(__file__), "../data/user_data.db"))
    # Make sure the data directory exists
    os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
    return sqlite3.connect(DB_PATH)

# Add this function to create subscription tables if needed
def initialize_database():
    """Initialize the database tables needed for subscriptions"""
    conn = get_db_connection()
    cursor = conn.cursor()
    
    # Check if subscriptions table exists
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='subscriptions'")
    if cursor.fetchone():
        # Table exists, check if required columns exist
        cursor.execute("PRAGMA table_info(subscriptions)")
        columns = [column[1] for column in cursor.fetchall()]
        
        # Check for missing columns and add them if needed
        if "user_id" not in columns:
            logger.info("Adding 'user_id' column to subscriptions table")
            cursor.execute("ALTER TABLE subscriptions ADD COLUMN user_id TEXT NOT NULL DEFAULT ''")
        
        if "created_at" not in columns:
            logger.info("Adding 'created_at' column to subscriptions table")
            cursor.execute("ALTER TABLE subscriptions ADD COLUMN created_at TIMESTAMP")
        
        if "expires_at" not in columns:
            logger.info("Adding 'expires_at' column to subscriptions table")
            cursor.execute("ALTER TABLE subscriptions ADD COLUMN expires_at TIMESTAMP")
        
        if "paypal_subscription_id" not in columns:
            logger.info("Adding 'paypal_subscription_id' column to subscriptions table")
            cursor.execute("ALTER TABLE subscriptions ADD COLUMN paypal_subscription_id TEXT")
    else:
        # Create subscriptions table with all required columns
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS subscriptions (
            id TEXT PRIMARY KEY,
            user_id TEXT NOT NULL,
            tier TEXT NOT NULL,
            status TEXT NOT NULL,
            created_at TIMESTAMP NOT NULL,
            expires_at TIMESTAMP,
            paypal_subscription_id TEXT
        )
        ''')
        logger.info("Created subscriptions table with all required columns")
    
    # Create PayPal plans table if it doesn't exist
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS paypal_plans (
        plan_id TEXT PRIMARY KEY,
        tier TEXT NOT NULL,
        price REAL NOT NULL,
        currency TEXT NOT NULL,
        created_at TIMESTAMP NOT NULL
    )
    ''')
    
    conn.commit()
    conn.close()
    logger.info("Database initialization completed")


def create_user_subscription_mock(user_email, tier):
    """
    Create a mock subscription for testing
    
    Args:
        user_email: The email of the user
        tier: The subscription tier
        
    Returns:
        tuple: (success, result)
    """
    try:
        logger.info(f"Creating mock subscription for {user_email} at tier {tier}")
        
        # Get user ID from email
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT id FROM users WHERE email = ?", (user_email,))
        user_result = cursor.fetchone()
        
        if not user_result:
            conn.close()
            return False, f"User not found: {user_email}"
        
        user_id = user_result[0]
        
        # Create a mock subscription ID
        subscription_id = f"mock_sub_{uuid.uuid4()}"
        
        # Store the subscription in database
        sub_id = str(uuid.uuid4())
        start_date = datetime.now()
        
        cursor.execute(
            "INSERT INTO subscriptions (id, user_id, tier, status, created_at, expires_at, paypal_subscription_id) VALUES (?, ?, ?, ?, ?, ?, ?)",
            (sub_id, user_id, tier, "active", start_date, start_date + timedelta(days=30), subscription_id)
        )
        
        # Update user's subscription tier
        cursor.execute(
            "UPDATE users SET subscription_tier = ? WHERE id = ?",
            (tier, user_id)
        )
        
        conn.commit()
        conn.close()
        
        # Use environment variable for the app URL
        app_url = os.getenv("APP_URL", "http://localhost:3000")
        
        # Return success with mock approval URL that matches the real PayPal URL pattern
        return True, {
            "subscription_id": subscription_id,
            "approval_url": f"{app_url}/subscription/callback?status=success&subscription_id={subscription_id}",
            "tier": tier
        }
        
    except Exception as e:
        logger.error(f"Error creating mock subscription: {str(e)}")
        return False, f"Error creating subscription: {str(e)}"

# Add this at the end of the file
def initialize():
    """Initialize the PayPal integration module"""
    try:
        # Create necessary directories
        os.makedirs(os.path.dirname(PLAN_IDS_PATH), exist_ok=True)
        
        # Initialize database
        initialize_database()
        
        # Initialize subscription plans
        plans = get_subscription_plans()
        if plans:
            logger.info(f"Subscription plans initialized: {plans}")
        else:
            logger.warning("Failed to initialize subscription plans")
            
        return True
    except Exception as e:
        logger.error(f"Error initializing PayPal integration: {str(e)}")
        return False

# Call initialize when the module is imported
initialize()

# Add this function to get subscription plans
def get_subscription_plans():
    """
    Get all available subscription plans with correct pricing
    """
    try:
        # Check if we have plan IDs saved in a file
        if os.path.exists(PLAN_IDS_PATH):
            try:
                with open(PLAN_IDS_PATH, 'r') as f:
                    plans = json.load(f)
                    logger.info(f"Loaded subscription plans from {PLAN_IDS_PATH}: {plans}")
                    return plans
            except Exception as e:
                logger.error(f"Error reading plan IDs file: {str(e)}")
                return {}
        
        # If no file exists, return empty dict
        logger.warning(f"No plan IDs file found at {PLAN_IDS_PATH}. Please initialize subscription plans.")
        return {}
        
    except Exception as e:
        logger.error(f"Error getting subscription plans: {str(e)}")
        return {}

# Add this function to create subscription tables if needed
def initialize_database():
    """Initialize the database tables needed for subscriptions"""
    conn = get_db_connection()
    cursor = conn.cursor()
    
    # Create subscriptions table if it doesn't exist
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS subscriptions (
        id TEXT PRIMARY KEY,
        user_id TEXT NOT NULL,
        tier TEXT NOT NULL,
        status TEXT NOT NULL,
        created_at TIMESTAMP NOT NULL,
        expires_at TIMESTAMP,
        paypal_subscription_id TEXT
    )
    ''')
    
    # Create PayPal plans table if it doesn't exist
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS paypal_plans (
        plan_id TEXT PRIMARY KEY,
        tier TEXT NOT NULL,
        price REAL NOT NULL,
        currency TEXT NOT NULL,
        created_at TIMESTAMP NOT NULL
    )
    ''')
    
    conn.commit()
    conn.close()


def create_user_subscription(user_email, tier):
    """
    Create a real PayPal subscription for a user
    
    Args:
        user_email: The email of the user
        tier: The subscription tier (standard_tier or premium_tier)
    
    Returns:
        tuple: (success, result)
            - success: True if successful, False otherwise
            - result: Dictionary with subscription details or error message
    """
    try:
        # Validate tier
        valid_tiers = ["standard_tier", "premium_tier"]
        if tier not in valid_tiers:
            return False, f"Invalid tier: {tier}. Must be one of {valid_tiers}"
        
        # Get the plan IDs
        plans = get_subscription_plans()
        
        # Log the plans for debugging
        logger.info(f"Available subscription plans: {plans}")
        
        # If no plans found, check if the file exists and try to load it directly
        if not plans:
            if os.path.exists(PLAN_IDS_PATH):
                logger.info(f"Plan IDs file exists at {PLAN_IDS_PATH}, but couldn't load plans. Trying direct load.")
                try:
                    with open(PLAN_IDS_PATH, 'r') as f:
                        plans = json.load(f)
                        logger.info(f"Directly loaded plans: {plans}")
                except Exception as e:
                    logger.error(f"Error directly loading plans: {str(e)}")
            else:
                logger.error(f"Plan IDs file does not exist at {PLAN_IDS_PATH}")
                
            # If still no plans, return error
            if not plans:
                logger.error("No PayPal plans found. Please initialize plans first.")
                return False, "PayPal plans not configured. Please contact support."
        
        # Check if the tier exists in plans
        if tier not in plans:
            return False, f"No plan found for tier: {tier}"
            
        # Use environment variable for the app URL
        app_url = os.getenv("APP_URL", "http://localhost:3000")
        
        # Create the subscription with PayPal
        payload = {
            "plan_id": plans[tier],
            "subscriber": {
                "email_address": user_email
            },
            "application_context": {
                "brand_name": "Legal Document Analyzer",
                "locale": "en-US",  # Changed from en_US to en-US
                "shipping_preference": "NO_SHIPPING",
                "user_action": "SUBSCRIBE_NOW",
                "return_url": f"{app_url}/subscription/callback?status=success",
                "cancel_url": f"{app_url}/subscription/callback?status=cancel"
            }
        }
        
        # Make the API call to PayPal
        success, subscription_data = call_paypal_api("/v1/billing/subscriptions", "POST", payload)
        if not success:
            return False, subscription_data  # This is already an error message
        
        # Extract the approval URL
        approval_url = next((link["href"] for link in subscription_data["links"] 
                            if link["rel"] == "approve"), None)
        
        if not approval_url:
            return False, "No approval URL found in PayPal response"
        
        # Get user ID from email
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT id FROM users WHERE email = ?", (user_email,))
        user_result = cursor.fetchone()
        
        if not user_result:
            conn.close()
            return False, f"User not found: {user_email}"
        
        user_id = user_result[0]
        
        # Store pending subscription in database
        sub_id = str(uuid.uuid4())
        start_date = datetime.now()
        
        cursor.execute(
            "INSERT INTO subscriptions (id, user_id, tier, status, created_at, expires_at, paypal_subscription_id) VALUES (?, ?, ?, ?, ?, ?, ?)",
            (sub_id, user_id, tier, "pending", start_date, None, subscription_data["id"])
        )
        
        conn.commit()
        conn.close()
        
        # Return success with approval URL
        return True, {
            "subscription_id": subscription_data["id"],
            "approval_url": approval_url,
            "tier": tier
        }
        
    except Exception as e:
        logger.error(f"Error creating user subscription: {str(e)}")
        return False, f"Error creating subscription: {str(e)}"

# Add a function to cancel a subscription
def cancel_subscription(subscription_id, reason="Customer requested cancellation"):
    """
    Cancel a PayPal subscription
    
    Args:
        subscription_id: The PayPal subscription ID
        reason: The reason for cancellation
        
    Returns:
        tuple: (success, result)
            - success: True if successful, False otherwise
            - result: Success message or error message
    """
    try:
        # Cancel the subscription with PayPal
        payload = {
            "reason": reason
        }
        
        success, result = call_paypal_api(
            f"/v1/billing/subscriptions/{subscription_id}/cancel", 
            "POST", 
            payload
        )
        
        if not success:
            return False, result
        
        # Update subscription status in database
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute(
            "UPDATE subscriptions SET status = 'cancelled' WHERE paypal_subscription_id = ?",
            (subscription_id,)
        )
        
        # Get the user ID for this subscription
        cursor.execute(
            "SELECT user_id FROM subscriptions WHERE paypal_subscription_id = ?",
            (subscription_id,)
        )
        user_result = cursor.fetchone()
        
        if user_result:
            # Update user to free tier
            cursor.execute(
                "UPDATE users SET subscription_tier = 'free_tier' WHERE id = ?",
                (user_result[0],)
            )
        
        conn.commit()
        conn.close()
        
        return True, "Subscription cancelled successfully"
        
    except Exception as e:
        logger.error(f"Error cancelling subscription: {str(e)}")
        return False, f"Error cancelling subscription: {str(e)}"

def verify_subscription_payment(subscription_id):
    """
    Verify a subscription payment with PayPal
    
    Args:
        subscription_id: The PayPal subscription ID
        
    Returns:
        tuple: (success, result)
            - success: True if successful, False otherwise
            - result: Dictionary with subscription details or error message
    """
    try:
        # Get subscription details from PayPal using our helper
        success, subscription_data = call_paypal_api(f"/v1/billing/subscriptions/{subscription_id}")
        if not success:
            return False, subscription_data  # This is already an error message
        
        # Check subscription status
        status = subscription_data.get("status", "").upper()
        
        if status not in ["ACTIVE", "APPROVED"]:
            return False, f"Subscription is not active: {status}"
        
        # Return success with subscription data
        return True, subscription_data
        
    except Exception as e:
        logger.error(f"Error verifying subscription: {str(e)}")
        return False, f"Error verifying subscription: {str(e)}"

def verify_paypal_subscription(subscription_id):
    """
    Verify a PayPal subscription
    
    Args:
        subscription_id: The PayPal subscription ID
        
    Returns:
        tuple: (success, result)
    """
    try:
        # Skip verification for mock subscriptions
        if subscription_id.startswith("mock_sub_"):
            return True, {"status": "ACTIVE"}
            
        # For real subscriptions, call PayPal API
        success, result = call_paypal_api(f"/v1/billing/subscriptions/{subscription_id}", "GET")
        
        if success:
            # Check subscription status
            if result.get("status") == "ACTIVE":
                return True, result
            else:
                return False, f"Subscription is not active: {result.get('status')}"
        else:
            logger.error(f"PayPal API error: {result}")
            return False, f"Failed to verify subscription: {result}"
    except Exception as e:
        logger.error(f"Error verifying PayPal subscription: {str(e)}")
        return False, f"Error verifying subscription: {str(e)}"

# Add this function to save subscription plans
def save_subscription_plans(plans):
    """
    Save subscription plans to a file
    
    Args:
        plans: Dictionary of plan IDs by tier
    """
    try:
        with open(PLAN_IDS_PATH, 'w') as f:
            json.dump(plans, f)
        logger.info(f"Saved subscription plans to {PLAN_IDS_PATH}")
        return True
    except Exception as e:
        logger.error(f"Error saving subscription plans: {str(e)}")
        return False