"""
Stripe Webhook Signal Handlers

Listens to dj-stripe signals to update TransactionLink and Event status.
"""
from django.dispatch import receiver
from djstripe.signals import WEBHOOK_SIGNALS, webhook_processing_error
from django.utils import timezone
from .models import TransactionLink
from smoothschedule.scheduling.schedule.models import Event
import logging

logger = logging.getLogger(__name__)


@receiver(webhook_processing_error)
def handle_webhook_error(sender, exception, event_type, **kwargs):
    """
    Log webhook processing errors for debugging.

    This helps identify issues with Stripe webhook delivery or processing.
    """
    logger.error(
        f"Stripe webhook error: {event_type}",
        extra={
            'exception': str(exception),
            'event_type': event_type,
            'sender': str(sender),
        },
        exc_info=exception
    )


@receiver(WEBHOOK_SIGNALS['payment_intent.succeeded'])
def handle_payment_succeeded(sender, event, **kwargs):
    """
    Handle successful payment and update Event status to PAID.
    
    This is triggered when a Stripe PaymentIntent succeeds.
    Updates the TransactionLink and marks the associated Event as PAID.
    """
    payment_intent = event.data.object
    payment_intent_id = payment_intent.id
    
    try:
        # Find the transaction link
        transaction = TransactionLink.objects.get(
            payment_intent_id=payment_intent_id
        )
        
        # Update transaction status
        transaction.status = TransactionLink.Status.SUCCEEDED
        transaction.completed_at = timezone.now()
        transaction.save()
        
        # Update the linked event status to PAID
        event_obj = transaction.event
        event_obj.status = Event.Status.PAID
        event_obj.save()
        
        logger.info(
            f"Payment succeeded for Event {event_obj.id}",
            extra={
                'payment_intent_id': payment_intent_id,
                'amount': transaction.amount,
                'event_id': event_obj.id,
                'tenant_revenue': float(transaction.tenant_revenue),
                'platform_revenue': float(transaction.platform_revenue),
            }
        )
        
    except TransactionLink.DoesNotExist:
        logger.warning(
            f"TransactionLink not found for PaymentIntent {payment_intent_id}"
        )
    except Exception as e:
        logger.error(
            f"Error processing payment_intent.succeeded: {str(e)}",
            exc_info=e
        )


@receiver(WEBHOOK_SIGNALS['payment_intent.payment_failed'])
def handle_payment_failed(sender, event, **kwargs):
    """Handle failed payments"""
    payment_intent = event.data.object
    payment_intent_id = payment_intent.id
    
    try:
        transaction = TransactionLink.objects.get(
            payment_intent_id=payment_intent_id
        )
        
        transaction.status = TransactionLink.Status.FAILED
        transaction.error_message = payment_intent.last_payment_error.message if payment_intent.last_payment_error else 'Unknown error'
        transaction.save()
        
        logger.warning(
            f"Payment failed for Event {transaction.event.id}",
            extra={
                'payment_intent_id': payment_intent_id,
                'error': transaction.error_message,
            }
        )
        
    except TransactionLink.DoesNotExist:
        logger.warning(f"TransactionLink not found for PaymentIntent {payment_intent_id}")
    except Exception as e:
        logger.error(f"Error processing payment_failed: {str(e)}", exc_info=e)


@receiver(WEBHOOK_SIGNALS['payment_intent.canceled'])
def handle_payment_canceled(sender, event, **kwargs):
    """Handle canceled payments"""
    payment_intent = event.data.object
    payment_intent_id = payment_intent.id
    
    try:
        transaction = TransactionLink.objects.get(
            payment_intent_id=payment_intent_id
        )
        
        transaction.status = TransactionLink.Status.CANCELED
        transaction.save()
        
        logger.info(f"Payment canceled for Event {transaction.event.id}")
        
    except TransactionLink.DoesNotExist:
        logger.warning(f"TransactionLink not found for PaymentIntent {payment_intent_id}")
    except Exception as e:
        logger.error(f"Error processing payment_canceled: {str(e)}", exc_info=e)
