import stripe
from flask import current_app
from decimal import Decimal
import logging

logger = logging.getLogger(__name__)

def validate_stripe_config():
    """Validate Stripe API configuration at startup - ONLY if payments are enabled"""
    
    # Check if payments feature is enabled
    features = current_app.config.get('FEATURES', {})
    if not features.get('payments', False):
        print("💳 Payments feature is disabled - skipping Stripe validation")
        return
    
    # Only validate if payments are enabled
    publishable_key = current_app.config.get('STRIPE_PUBLISHABLE_KEY')
    secret_key = current_app.config.get('STRIPE_SECRET_KEY')
    
    if not publishable_key:
        print("⚠️  STRIPE_PUBLISHABLE_KEY not set - using dummy key for disabled payments")
        return
    if not secret_key:
        print("⚠️  STRIPE_SECRET_KEY not set - using dummy key for disabled payments")
        return
    
    # Test API connectivity (graceful failure during deployment)
    stripe.api_key = secret_key
    try:
        stripe.Account.retrieve()
        print("✓ Stripe API connection validated")
    except stripe.error.AuthenticationError:
        print("⚠️  Stripe API credentials invalid - payment features will be disabled")
        print("   This is normal during deployment. Payment system will work when keys are valid.")
    except Exception as e:
        print(f"⚠️  Stripe API connection failed: {str(e)}")
        print("   Payment system will retry connection when needed.")

class StripeService:
    """Stripe payment processing for Australian construction marketplace"""
    
    def __init__(self):
        # Initialize stripe.api_key only when needed, not at import time
        pass
    
    def _ensure_stripe_key(self):
        """Ensure Stripe API key is set before making API calls"""
        if not stripe.api_key:
            stripe.api_key = current_app.config.get('STRIPE_SECRET_KEY')
    
    def create_payment_intent(self, amount_aud, currency='aud', metadata=None):
        """Create Stripe PaymentIntent for escrow payment"""
        self._ensure_stripe_key()
        try:
            # Convert to cents (Stripe uses smallest currency unit)
            amount_cents = int(float(amount_aud) * 100)
            
            intent = stripe.PaymentIntent.create(
                amount=amount_cents,
                currency=currency,
                metadata=metadata or {},
                capture_method='manual',  # For escrow - capture later
                description='RateRight Construction Job Payment'
            )
            
            logger.info(f"Created PaymentIntent: {intent.id} for ${amount_aud} AUD")
            return intent
            
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating PaymentIntent: {str(e)}")
            raise Exception(f"Payment processing error: {str(e)}")
    
    def capture_payment(self, payment_intent_id, amount_to_capture=None):
        """Capture payment from escrow when work is completed"""
        self._ensure_stripe_key()
        try:
            intent = stripe.PaymentIntent.retrieve(payment_intent_id)
            
            if amount_to_capture:
                amount_cents = int(float(amount_to_capture) * 100)
                captured = stripe.PaymentIntent.capture(
                    payment_intent_id,
                    amount_to_capture=amount_cents
                )
            else:
                captured = stripe.PaymentIntent.capture(payment_intent_id)
            
            logger.info(f"Captured payment: {payment_intent_id}")
            return captured
            
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error capturing payment: {str(e)}")
            raise Exception(f"Payment capture error: {str(e)}")
    
    def refund_payment(self, payment_intent_id, amount_to_refund=None, reason='requested_by_customer'):
        """Refund payment (for disputes or cancellations)"""
        self._ensure_stripe_key()
        try:
            refund_data = {
                'payment_intent': payment_intent_id,
                'reason': reason
            }
            
            if amount_to_refund:
                refund_data['amount'] = int(float(amount_to_refund) * 100)
            
            refund = stripe.Refund.create(**refund_data)
            
            logger.info(f"Created refund: {refund.id} for PaymentIntent: {payment_intent_id}")
            return refund
            
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating refund: {str(e)}")
            raise Exception(f"Refund processing error: {str(e)}")
    
    def create_connect_account(self, user_data):
        """Create Stripe Connect account for contractors/workers"""
        self._ensure_stripe_key()
        try:
            account = stripe.Account.create(
                type='express',
                country='AU',
                email=user_data.get('email'),
                business_type='individual',
                individual={
                    'first_name': user_data.get('first_name'),
                    'last_name': user_data.get('last_name'),
                    'email': user_data.get('email')
                },
                capabilities={
                    'card_payments': {'requested': True},
                    'transfers': {'requested': True}
                }
            )
            
            logger.info(f"Created Stripe Connect account: {account.id}")
            return account
            
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating Connect account: {str(e)}")
            raise Exception(f"Account creation error: {str(e)}")
    
    def transfer_to_worker(self, amount_aud, destination_account_id, metadata=None):
        """Transfer payment to worker after escrow release"""
        self._ensure_stripe_key()
        try:
            amount_cents = int(float(amount_aud) * 100)
            
            transfer = stripe.Transfer.create(
                amount=amount_cents,
                currency='aud',
                destination=destination_account_id,
                metadata=metadata or {}
            )
            
            logger.info(f"Created transfer: {transfer.id} to {destination_account_id}")
            return transfer
            
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating transfer: {str(e)}")
            raise Exception(f"Transfer error: {str(e)}")

# Initialize service
stripe_service = StripeService()
