"""
Token Management API Routes
Handles AI token balance, purchases, transactions, and analytics
"""

from flask import Blueprint, request, jsonify, g
from services.token_manager import TokenManager
from database import get_db_connection
from utils.decorators import require_api_key, require_admin
from auth.jwt_manager import optional_auth
from utils.response_helpers import create_success_response, create_error_response
import logging
import traceback
import json

logger = logging.getLogger(__name__)

token_bp = Blueprint('token', __name__)


# ============================================================================
# TOKEN PACKAGES - Public endpoints
# ============================================================================

@token_bp.route('/api/tokens/packages', methods=['GET'])
def get_token_packages():
    """Get all available token packages from subscription_plans"""
    from database import get_db_connection
    import json
    
    try:
        conn = get_db_connection()
        cursor = conn.cursor(dictionary=True)
        
        # Query subscription_plans for AI token packages
        cursor.execute("""
            SELECT 
                sp.id,
                sp.plan_name as package_name,
                sp.description,
                sp.price_monthly as price_npr,
                sp.price_monthly * 0.0075 as price_usd,
                sp.benefits,
                sp.features_list as features,
                sp.is_popular,
                sp.display_order,
                sp.tier
            FROM subscription_plans sp
            JOIN subscription_types st ON sp.subscription_type_id = st.id
            WHERE st.type_key = 'ai_tokens' AND sp.is_active = TRUE
            ORDER BY sp.display_order ASC
        """)
        
        packages = cursor.fetchall()
        
        # Transform to frontend expected format
        result_packages = []
        for pkg in packages:
            benefits = pkg.get('benefits', {})
            if isinstance(benefits, str):
                benefits = json.loads(benefits)
            
            features = pkg.get('features', [])
            if isinstance(features, str):
                features = json.loads(features)
            
            ai_benefits = benefits.get('ai_tokens', {})
            
            result_packages.append({
                'id': pkg['id'],
                'package_name': pkg['package_name'],
                'description': pkg['description'],
                'tokens': ai_benefits.get('monthly_allowance', 0),
                'price_npr': float(pkg['price_npr'] or 0),
                'price_usd': float(pkg['price_usd'] or 0),
                'grants_models': ai_benefits.get('model_access', []),
                'validity_days': 30,  # Monthly subscriptions
                'is_popular': pkg['is_popular'] or False,
                'features': features,
                'tier': pkg['tier']
            })
        
        return create_success_response(
            data={'packages': result_packages},
            message='Token packages retrieved successfully'
        )
        
    except Exception as e:
        logger.error(f"Error getting token packages: {e}")
        import traceback
        traceback.print_exc()
        return create_error_response(str(e))
    finally:
        if conn:
            conn.close()


# ============================================================================
# USER TOKEN MANAGEMENT
# ============================================================================

@token_bp.route('/api/tokens/balance', methods=['GET'])
@require_api_key
@optional_auth
def get_token_balance():
    """Get current user's token balance"""
    user_id = g.current_user_id
    
    balance_info = TokenManager.get_user_balance(user_id)
    
    return create_success_response(
        data={'data': balance_info},
        message='Token balance retrieved successfully'
    )


@token_bp.route('/api/tokens/check-balance', methods=['POST'])
@require_api_key
def check_token_balance():
    """Check if user has sufficient tokens for an operation"""
    user_id = g.current_user_id
    data = request.get_json()
    
    required_tokens = data.get('required_tokens', 0)
    
    result = TokenManager.check_balance(user_id, required_tokens)
    
    return create_success_response(
        data=result,
        message='Balance check completed'
    )


@token_bp.route('/api/tokens/purchase', methods=['POST'])
@require_api_key
@optional_auth
def purchase_tokens():
    """Purchase a token package (creates subscription)"""
    # Get user_id from JWT auth or request data
    user_id = getattr(g, 'current_user_id', None)
    data = request.get_json()
    
    if not user_id:
        user_id = data.get('user_id')
    
    if not user_id:
        return create_error_response('user_id is required', status_code=400)
    
    package_id = data.get('package_id')
    payment_data = data.get('payment_data', {})
    
    if not package_id:
        return create_error_response('package_id is required', status_code=400)
    
    # Get package details from subscription_plans
    from database import get_db_connection
    from services.subscription_manager import SubscriptionManager
    try:
        conn = get_db_connection()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute("""
            SELECT sp.*, st.type_key
            FROM subscription_plans sp
            JOIN subscription_types st ON sp.subscription_type_id = st.id
            WHERE sp.id = %s AND sp.is_active = TRUE
        """, (package_id,))
        
        package = cursor.fetchone()
        
        if not package:
            return create_error_response('Invalid or inactive package', status_code=400)
        
        # Parse benefits to get token amount
        import json
        benefits = package.get('benefits', {})
        if isinstance(benefits, str):
            benefits = json.loads(benefits)
        
        ai_benefits = benefits.get('ai_tokens', {})
        tokens_to_add = ai_benefits.get('monthly_allowance', 0)
        
        # Add tokens to user account
        result = TokenManager.add_tokens(
            user_id=user_id,
            amount=float(tokens_to_add),
            transaction_type='purchase',
            purchase_package_id=package_id,
            payment_id=payment_data.get('payment_id'),
            payment_method=payment_data.get('method'),
            payment_amount=float(package['price_monthly'] or 0),
            notes=f'Purchased {package["plan_name"]}'
        )
        
        if result['success']:
            # Create or update subscription
            sub_result = SubscriptionManager.create_subscription(
                user_id=user_id,
                plan_id=package_id,
                billing_cycle='monthly',
                payment_data=payment_data
            )
            
            return create_success_response(
                data={
                    **result,
                    'package_name': package['plan_name'],
                    'tokens_added': tokens_to_add,
                    'subscription_id': sub_result.get('subscription_id')
                },
                message=f'Successfully purchased {package["plan_name"]}'
            )
        else:
            return create_error_response(
                result.get('message', 'Failed to process purchase'),
                status_code=500
            )
            
    except Exception as e:
        logger.error(f"Error purchasing tokens: {e}")
        import traceback
        traceback.print_exc()
        return create_error_response(str(e), status_code=500)
    finally:
        if conn:
            conn.close()


@token_bp.route('/api/tokens/transactions', methods=['GET'])
@require_api_key
@optional_auth
def get_token_transactions():
    """Get user's token transaction history"""
    user_id = g.current_user_id
    
    limit = int(request.args.get('limit', 50))
    offset = int(request.args.get('offset', 0))
    transaction_type = request.args.get('type')  # consumption, purchase, etc.
    
    result = TokenManager.get_transaction_history(
        user_id=user_id,
        limit=limit,
        offset=offset,
        transaction_type=transaction_type
    )
    
    return create_success_response(
        data={'data': result},
        message='Transaction history retrieved successfully'
    )


@token_bp.route('/api/tokens/analytics', methods=['GET'])
@require_api_key
def get_token_analytics():
    """Get AI usage analytics for current user"""
    user_id = g.current_user_id
    
    days = int(request.args.get('days', 30))
    
    analytics = TokenManager.get_usage_analytics(user_id, days)
    
    return create_success_response(
        data=analytics,
        message='Usage analytics retrieved successfully'
    )


# ============================================================================
# ADMIN ENDPOINTS
# ============================================================================

@token_bp.route('/api/admin/tokens/credit', methods=['POST'])
@require_admin
def admin_credit_tokens():
    """Manually credit tokens to a user (admin only)"""
    data = request.get_json()
    
    user_id = data.get('user_id')
    amount = data.get('amount')
    notes = data.get('notes', 'Admin credit')
    
    if not user_id or not amount:
        return create_error_response('user_id and amount are required', status_code=400)
    
    result = TokenManager.add_tokens(
        user_id=user_id,
        amount=float(amount),
        transaction_type='admin_credit',
        notes=notes
    )
    
    if result['success']:
        return create_success_response(
            data=result,
            message=f'Successfully credited {amount} tokens to user {user_id}'
        )
    else:
        return create_error_response(
            result.get('message', 'Failed to credit tokens'),
            status_code=500
        )


@token_bp.route('/api/admin/tokens/packages/create', methods=['POST'])
@require_admin
def admin_create_package():
    """Create a new token package (admin only)"""
    from database import get_db_connection
    import json
    
    data = request.get_json()
    
    try:
        conn = get_db_connection()
        cursor = conn.cursor()
        
        cursor.execute("""
            INSERT INTO ai_token_packages (
                package_name, description, token_amount, bonus_tokens,
                price_npr, price_usd, discount_percentage, is_popular,
                validity_days, features, display_order
            ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        """, (
            data.get('package_name'),
            data.get('description'),
            data.get('token_amount'),
            data.get('bonus_tokens', 0),
            data.get('price_npr'),
            data.get('price_usd'),
            data.get('discount_percentage', 0),
            data.get('is_popular', False),
            data.get('validity_days'),
            json.dumps(data.get('features')) if data.get('features') else None,
            data.get('display_order', 0)
        ))
        
        package_id = cursor.lastrowid
        conn.commit()
        
        return create_success_response(
            data={'package_id': package_id},
            message='Token package created successfully'
        )
        
    except Exception as e:
        if conn:
            conn.rollback()
        logger.error(f"Error creating token package: {e}")
        return create_error_response(str(e), status_code=500)
    finally:
        if conn:
            conn.close()
