"""
Background tasks for moderation workflows and notifications.
"""

import logging
from celery import shared_task
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from django.utils import timezone

logger = logging.getLogger(__name__)


@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def send_moderation_notification(self, submission_id, status):
    """
    Send email notification when a submission is approved or rejected.
    
    Args:
        submission_id: UUID of the ContentSubmission
        status: 'approved' or 'rejected'
        
    Returns:
        str: Notification result message
    """
    from apps.moderation.models import ContentSubmission
    
    try:
        submission = ContentSubmission.objects.select_related(
            'user', 'reviewed_by', 'entity_type'
        ).prefetch_related('items').get(id=submission_id)
        
        # Get user's submission count
        user_submission_count = ContentSubmission.objects.filter(
            user=submission.user
        ).count()
        
        # Prepare email context
        context = {
            'submission': submission,
            'status': status,
            'user': submission.user,
            'user_submission_count': user_submission_count,
            'submission_url': f"{settings.SITE_URL}/submissions/{submission.id}/",
            'site_url': settings.SITE_URL,
        }
        
        # Choose template based on status
        if status == 'approved':
            template = 'emails/moderation_approved.html'
            subject = f'✅ Submission Approved: {submission.title}'
        else:
            template = 'emails/moderation_rejected.html'
            subject = f'⚠️ Submission Requires Changes: {submission.title}'
        
        # Render HTML email
        html_message = render_to_string(template, context)
        
        # Send email
        send_mail(
            subject=subject,
            message='',  # Plain text version (optional)
            html_message=html_message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[submission.user.email],
            fail_silently=False,
        )
        
        logger.info(
            f"Moderation notification sent: {status} for submission {submission_id} "
            f"to {submission.user.email}"
        )
        
        return f"Notification sent to {submission.user.email}"
        
    except ContentSubmission.DoesNotExist:
        logger.error(f"Submission {submission_id} not found")
        raise
    except Exception as exc:
        logger.error(f"Error sending notification for submission {submission_id}: {str(exc)}")
        # Retry with exponential backoff
        raise self.retry(exc=exc, countdown=60 * (2 ** self.request.retries))


@shared_task(bind=True, max_retries=2)
def cleanup_expired_locks(self):
    """
    Clean up expired moderation locks.
    
    This task runs periodically to unlock submissions that have
    been locked for too long (default: 15 minutes).
    
    Returns:
        int: Number of locks cleaned up
    """
    from apps.moderation.models import ModerationLock
    
    try:
        cleaned = ModerationLock.cleanup_expired()
        logger.info(f"Cleaned up {cleaned} expired moderation locks")
        return cleaned
        
    except Exception as exc:
        logger.error(f"Error cleaning up expired locks: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)  # Retry after 5 minutes


@shared_task(bind=True, max_retries=3)
def send_batch_moderation_summary(self, moderator_id):
    """
    Send a daily summary email to a moderator with their moderation stats.
    
    Args:
        moderator_id: ID of the moderator user
        
    Returns:
        str: Email send result
    """
    from apps.users.models import User
    from apps.moderation.models import ContentSubmission
    from datetime import timedelta
    
    try:
        moderator = User.objects.get(id=moderator_id)
        
        # Get stats for the past 24 hours
        yesterday = timezone.now() - timedelta(days=1)
        
        stats = {
            'reviewed_today': ContentSubmission.objects.filter(
                reviewed_by=moderator,
                reviewed_at__gte=yesterday
            ).count(),
            'approved_today': ContentSubmission.objects.filter(
                reviewed_by=moderator,
                reviewed_at__gte=yesterday,
                status='approved'
            ).count(),
            'rejected_today': ContentSubmission.objects.filter(
                reviewed_by=moderator,
                reviewed_at__gte=yesterday,
                status='rejected'
            ).count(),
            'pending_queue': ContentSubmission.objects.filter(
                status='pending'
            ).count(),
        }
        
        context = {
            'moderator': moderator,
            'stats': stats,
            'date': timezone.now(),
            'site_url': settings.SITE_URL,
        }
        
        # For now, just log the stats (template not created yet)
        logger.info(f"Moderation summary for {moderator.email}: {stats}")
        
        # In production, you would send an actual email:
        # html_message = render_to_string('emails/moderation_summary.html', context)
        # send_mail(...)
        
        return f"Summary sent to {moderator.email}"
        
    except User.DoesNotExist:
        logger.error(f"Moderator {moderator_id} not found")
        raise
    except Exception as exc:
        logger.error(f"Error sending moderation summary: {str(exc)}")
        raise self.retry(exc=exc, countdown=60 * (2 ** self.request.retries))


@shared_task
def update_moderation_statistics():
    """
    Update moderation-related statistics across the database.
    
    Returns:
        dict: Updated statistics
    """
    from apps.moderation.models import ContentSubmission
    from django.db.models import Count, Avg, F
    from datetime import timedelta
    
    try:
        now = timezone.now()
        week_ago = now - timedelta(days=7)
        
        stats = {
            'total_submissions': ContentSubmission.objects.count(),
            'pending': ContentSubmission.objects.filter(status='pending').count(),
            'reviewing': ContentSubmission.objects.filter(status='reviewing').count(),
            'approved': ContentSubmission.objects.filter(status='approved').count(),
            'rejected': ContentSubmission.objects.filter(status='rejected').count(),
            'this_week': ContentSubmission.objects.filter(
                created_at__gte=week_ago
            ).count(),
            'by_type': dict(
                ContentSubmission.objects.values('submission_type')
                .annotate(count=Count('id'))
                .values_list('submission_type', 'count')
            ),
        }
        
        logger.info(f"Moderation statistics updated: {stats}")
        return stats
        
    except Exception as e:
        logger.error(f"Error updating moderation statistics: {str(e)}")
        raise


@shared_task(bind=True, max_retries=2)
def auto_unlock_stale_reviews(self, hours=1):
    """
    Automatically unlock submissions that have been in review for too long.
    
    This helps prevent submissions from getting stuck if a moderator
    starts a review but doesn't complete it.
    
    Args:
        hours: Number of hours before auto-unlocking (default: 1)
        
    Returns:
        int: Number of submissions unlocked
    """
    from apps.moderation.models import ContentSubmission
    from apps.moderation.services import ModerationService
    from datetime import timedelta
    
    try:
        cutoff = timezone.now() - timedelta(hours=hours)
        
        # Find submissions that have been reviewing too long
        stale_reviews = ContentSubmission.objects.filter(
            status='reviewing',
            locked_at__lt=cutoff
        )
        
        count = 0
        for submission in stale_reviews:
            try:
                ModerationService.unlock_submission(submission.id)
                count += 1
            except Exception as e:
                logger.error(f"Failed to unlock submission {submission.id}: {str(e)}")
                continue
        
        logger.info(f"Auto-unlocked {count} stale reviews")
        return count
        
    except Exception as exc:
        logger.error(f"Error auto-unlocking stale reviews: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)


@shared_task
def notify_moderators_of_queue_size():
    """
    Notify moderators when the pending queue gets too large.
    
    This helps ensure timely review of submissions.
    
    Returns:
        dict: Notification result
    """
    from apps.moderation.models import ContentSubmission
    from apps.users.models import User
    
    try:
        pending_count = ContentSubmission.objects.filter(status='pending').count()
        
        # Threshold for notification (configurable)
        threshold = getattr(settings, 'MODERATION_QUEUE_THRESHOLD', 50)
        
        if pending_count >= threshold:
            # Get all moderators
            moderators = User.objects.filter(role__is_moderator=True)
            
            logger.warning(
                f"Moderation queue size ({pending_count}) exceeds threshold ({threshold}). "
                f"Notifying {moderators.count()} moderators."
            )
            
            # In production, send emails to moderators
            # For now, just log
            
            return {
                'queue_size': pending_count,
                'threshold': threshold,
                'notified': moderators.count(),
            }
        else:
            logger.info(f"Moderation queue size ({pending_count}) is within threshold")
            return {
                'queue_size': pending_count,
                'threshold': threshold,
                'notified': 0,
            }
        
    except Exception as e:
        logger.error(f"Error checking moderation queue: {str(e)}")
        raise
