"""
Stripe Payment Service - Handle subscriptions and payments.

Subscription Plans:
- Monthly: $49/mo
- Annual: $499/yr (save $89)
- Lifetime: $999
"""

import stripe
import os
from typing import Dict, Optional
from datetime import datetime, timedelta
import secrets
import structlog

logger = structlog.get_logger(__name__)


class StripeService:
    """Stripe payment integration."""
    
    def __init__(self, api_key: Optional[str] = None):
        self.api_key = api_key or os.getenv('STRIPE_SECRET_KEY')
        if self.api_key:
            stripe.api_key = self.api_key
        
        # Price IDs (set these in Stripe dashboard)
        self.PRICE_IDS = {
            'monthly': os.getenv('STRIPE_MONTHLY_PRICE_ID', 'price_monthly_placeholder'),
            'annual': os.getenv('STRIPE_ANNUAL_PRICE_ID', 'price_annual_placeholder'),
            'lifetime': os.getenv('STRIPE_LIFETIME_PRICE_ID', 'price_lifetime_placeholder')
        }
    
    def create_checkout_session(
        self,
        tier: str,
        period: str,
        customer_email: str,
        success_url: str,
        cancel_url: str
    ) -> Dict:
        """
        Create Stripe Checkout session.
        
        Args:
            tier: 'pro' or 'enterprise'
            period: 'monthly', 'annual', or 'lifetime'
            customer_email: Customer email
            success_url: Redirect on success
            cancel_url: Redirect on cancel
            
        Returns:
            Checkout session data
        """
        try:
            price_id = self.PRICE_IDS.get(period)
            
            if not price_id:
                raise ValueError(f"Invalid period: {period}")
            
            # Create checkout session
            session = stripe.checkout.Session.create(
                payment_method_types=['card'],
                line_items=[{
                    'price': price_id,
                    'quantity': 1,
                }],
                mode='subscription' if period != 'lifetime' else 'payment',
                success_url=success_url + '?session_id={CHECKOUT_SESSION_ID}',
                cancel_url=cancel_url,
                customer_email=customer_email,
                metadata={
                    'tier': tier,
                    'period': period
                }
            )
            
            logger.info("checkout_session_created",
                session_id=session.id,
                email=customer_email,
                tier=tier,
                period=period)
            
            return {
                'session_id': session.id,
                'url': session.url,
                'amount': session.amount_total,
                'currency': session.currency
            }
        
        except Exception as e:
            logger.error("checkout_session_error", error=str(e))
            raise
    
    def handle_webhook(self, payload: bytes, sig_header: str) -> Dict:
        """
        Handle Stripe webhook events.
        
        Args:
            payload: Request body
            sig_header: Stripe signature header
            
        Returns:
            Event data
        """
        webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET')
        
        try:
            event = stripe.Webhook.construct_event(
                payload, sig_header, webhook_secret
            )
            
            logger.info("webhook_received", event_type=event['type'])
            
            # Handle different event types
            if event['type'] == 'checkout.session.completed':
                return self._handle_checkout_completed(event)
            
            elif event['type'] == 'customer.subscription.deleted':
                return self._handle_subscription_deleted(event)
            
            elif event['type'] == 'invoice.payment_failed':
                return self._handle_payment_failed(event)
            
            return {'status': 'unhandled', 'type': event['type']}
        
        except Exception as e:
            logger.error("webhook_error", error=str(e))
            raise
    
    def _handle_checkout_completed(self, event: Dict) -> Dict:
        """Handle successful checkout."""
        session = event['data']['object']
        
        customer_email = session.get('customer_email')
        tier = session['metadata'].get('tier', 'pro')
        period = session['metadata'].get('period', 'monthly')
        
        # Generate license key
        from app.licensing.advanced_license_manager import AdvancedLicenseManager
        license_manager = AdvancedLicenseManager()
        
        if period == 'lifetime':
            expiry = None
        elif period == 'annual':
            expiry = datetime.now() + timedelta(days=365)
        else:  # monthly
            expiry = datetime.now() + timedelta(days=30)
        
        license_key = license_manager.generate_license_key(
            email=customer_email,
            tier=tier,
            expiry=expiry
        )
        
        logger.info("license_generated",
            email=customer_email,
            tier=tier,
            period=period)
        
        # Send license via email
        from app.emails.sendgrid_service import SendGridService
        email_service = SendGridService()
        email_service.send_license_email(
            to_email=customer_email,
            license_key=license_key,
            tier=tier,
            period=period
        )
        
        return {
            'status': 'success',
            'email': customer_email,
            'license_key': license_key,
            'tier': tier,
            'period': period
        }
    
    def _handle_subscription_deleted(self, event: Dict) -> Dict:
        """Handle subscription cancellation."""
        subscription = event['data']['object']
        customer_email = subscription.get('customer_email')
        
        logger.info("subscription_deleted", email=customer_email)
        
        # Revoke license (in production, update database)
        return {'status': 'revoked', 'email': customer_email}
    
    def _handle_payment_failed(self, event: Dict) -> Dict:
        """Handle failed payment."""
        invoice = event['data']['object']
        customer_email = invoice.get('customer_email')
        
        logger.warning("payment_failed", email=customer_email)
        
        # Send email notification
        from app.emails.sendgrid_service import SendGridService
        email_service = SendGridService()
        email_service.send_payment_failed_email(customer_email)
        
        return {'status': 'payment_failed', 'email': customer_email}
    
    def get_subscription_info(self, customer_email: str) -> Optional[Dict]:
        """Get customer subscription information."""
        try:
            # Search for customer
            customers = stripe.Customer.list(email=customer_email, limit=1)
            
            if not customers.data:
                return None
            
            customer = customers.data[0]
            
            # Get subscriptions
            subscriptions = stripe.Subscription.list(
                customer=customer.id,
                status='active',
                limit=1
            )
            
            if not subscriptions.data:
                return None
            
            subscription = subscriptions.data[0]
            
            return {
                'customer_id': customer.id,
                'subscription_id': subscription.id,
                'status': subscription.status,
                'current_period_end': datetime.fromtimestamp(subscription.current_period_end),
                'cancel_at_period_end': subscription.cancel_at_period_end
            }
        
        except Exception as e:
            logger.error("get_subscription_error", error=str(e))
            return None
