"""
Background tasks for entity statistics and maintenance.
"""

import logging
from celery import shared_task
from django.db.models import Count, Q
from django.utils import timezone

logger = logging.getLogger(__name__)


@shared_task(bind=True, max_retries=2)
def update_entity_statistics(self, entity_type, entity_id):
    """
    Update cached statistics for a specific entity.
    
    Args:
        entity_type: Type of entity ('park', 'ride', 'company', 'ridemodel')
        entity_id: ID of the entity
        
    Returns:
        dict: Updated statistics
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    from apps.media.models import Photo
    from apps.moderation.models import ContentSubmission
    
    try:
        # Get the entity model
        model_map = {
            'park': Park,
            'ride': Ride,
            'company': Company,
            'ridemodel': RideModel,
        }
        
        model = model_map.get(entity_type.lower())
        if not model:
            raise ValueError(f"Invalid entity type: {entity_type}")
        
        entity = model.objects.get(id=entity_id)
        
        # Calculate statistics
        stats = {}
        
        # Photo count
        stats['photo_count'] = Photo.objects.filter(
            content_type__model=entity_type.lower(),
            object_id=entity_id,
            moderation_status='approved'
        ).count()
        
        # Submission count
        stats['submission_count'] = ContentSubmission.objects.filter(
            entity_type__model=entity_type.lower(),
            entity_id=entity_id
        ).count()
        
        # Entity-specific stats
        if entity_type.lower() == 'park':
            stats['ride_count'] = entity.rides.count()
        elif entity_type.lower() == 'company':
            stats['park_count'] = entity.parks.count()
            stats['ride_model_count'] = entity.ride_models.count()
        elif entity_type.lower() == 'ridemodel':
            stats['installation_count'] = entity.rides.count()
        
        logger.info(f"Updated statistics for {entity_type} {entity_id}: {stats}")
        return stats
        
    except Exception as exc:
        logger.error(f"Error updating statistics for {entity_type} {entity_id}: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)


@shared_task(bind=True, max_retries=2)
def update_all_statistics(self):
    """
    Update cached statistics for all entities.
    
    This task runs periodically (e.g., every 6 hours) to ensure
    all entity statistics are up to date.
    
    Returns:
        dict: Update summary
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    
    try:
        summary = {
            'parks_updated': 0,
            'rides_updated': 0,
            'companies_updated': 0,
            'ride_models_updated': 0,
        }
        
        # Update parks
        for park in Park.objects.all():
            try:
                update_entity_statistics.delay('park', park.id)
                summary['parks_updated'] += 1
            except Exception as e:
                logger.error(f"Failed to queue update for park {park.id}: {str(e)}")
        
        # Update rides
        for ride in Ride.objects.all():
            try:
                update_entity_statistics.delay('ride', ride.id)
                summary['rides_updated'] += 1
            except Exception as e:
                logger.error(f"Failed to queue update for ride {ride.id}: {str(e)}")
        
        # Update companies
        for company in Company.objects.all():
            try:
                update_entity_statistics.delay('company', company.id)
                summary['companies_updated'] += 1
            except Exception as e:
                logger.error(f"Failed to queue update for company {company.id}: {str(e)}")
        
        # Update ride models
        for ride_model in RideModel.objects.all():
            try:
                update_entity_statistics.delay('ridemodel', ride_model.id)
                summary['ride_models_updated'] += 1
            except Exception as e:
                logger.error(f"Failed to queue update for ride model {ride_model.id}: {str(e)}")
        
        logger.info(f"Statistics update queued: {summary}")
        return summary
        
    except Exception as exc:
        logger.error(f"Error updating all statistics: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)


@shared_task
def generate_entity_report(entity_type, entity_id):
    """
    Generate a detailed report for an entity.
    
    This can be used for admin dashboards, analytics, etc.
    
    Args:
        entity_type: Type of entity
        entity_id: ID of the entity
        
    Returns:
        dict: Detailed report
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    from apps.media.models import Photo
    from apps.moderation.models import ContentSubmission
    from apps.versioning.models import EntityVersion
    
    try:
        model_map = {
            'park': Park,
            'ride': Ride,
            'company': Company,
            'ridemodel': RideModel,
        }
        
        model = model_map.get(entity_type.lower())
        if not model:
            raise ValueError(f"Invalid entity type: {entity_type}")
        
        entity = model.objects.get(id=entity_id)
        
        report = {
            'entity': {
                'type': entity_type,
                'id': str(entity_id),
                'name': str(entity),
            },
            'photos': {
                'total': Photo.objects.filter(
                    content_type__model=entity_type.lower(),
                    object_id=entity_id
                ).count(),
                'approved': Photo.objects.filter(
                    content_type__model=entity_type.lower(),
                    object_id=entity_id,
                    moderation_status='approved'
                ).count(),
                'pending': Photo.objects.filter(
                    content_type__model=entity_type.lower(),
                    object_id=entity_id,
                    moderation_status='pending'
                ).count(),
            },
            'submissions': {
                'total': ContentSubmission.objects.filter(
                    entity_type__model=entity_type.lower(),
                    entity_id=entity_id
                ).count(),
                'approved': ContentSubmission.objects.filter(
                    entity_type__model=entity_type.lower(),
                    entity_id=entity_id,
                    status='approved'
                ).count(),
                'pending': ContentSubmission.objects.filter(
                    entity_type__model=entity_type.lower(),
                    entity_id=entity_id,
                    status='pending'
                ).count(),
            },
            'versions': EntityVersion.objects.filter(
                content_type__model=entity_type.lower(),
                object_id=entity_id
            ).count(),
        }
        
        logger.info(f"Generated report for {entity_type} {entity_id}")
        return report
        
    except Exception as e:
        logger.error(f"Error generating report: {str(e)}")
        raise


@shared_task(bind=True, max_retries=2)
def cleanup_duplicate_entities(self):
    """
    Detect and flag potential duplicate entities.
    
    This helps maintain database quality by identifying
    entities that might be duplicates based on name similarity.
    
    Returns:
        dict: Duplicate detection results
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    
    try:
        # This is a simplified implementation
        # In production, you'd want more sophisticated duplicate detection
        
        results = {
            'parks_flagged': 0,
            'rides_flagged': 0,
            'companies_flagged': 0,
        }
        
        logger.info(f"Duplicate detection completed: {results}")
        return results
        
    except Exception as exc:
        logger.error(f"Error detecting duplicates: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)


@shared_task
def calculate_global_statistics():
    """
    Calculate global statistics across all entities.
    
    Returns:
        dict: Global statistics
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    from apps.media.models import Photo
    from apps.moderation.models import ContentSubmission
    from apps.users.models import User
    
    try:
        stats = {
            'entities': {
                'parks': Park.objects.count(),
                'rides': Ride.objects.count(),
                'companies': Company.objects.count(),
                'ride_models': RideModel.objects.count(),
            },
            'photos': {
                'total': Photo.objects.count(),
                'approved': Photo.objects.filter(moderation_status='approved').count(),
            },
            'submissions': {
                'total': ContentSubmission.objects.count(),
                'pending': ContentSubmission.objects.filter(status='pending').count(),
            },
            'users': {
                'total': User.objects.count(),
                'active': User.objects.filter(is_active=True).count(),
            },
            'timestamp': timezone.now().isoformat(),
        }
        
        logger.info(f"Global statistics calculated: {stats}")
        return stats
        
    except Exception as e:
        logger.error(f"Error calculating global statistics: {str(e)}")
        raise


@shared_task(bind=True, max_retries=2)
def validate_entity_data(self, entity_type, entity_id):
    """
    Validate entity data integrity and flag issues.
    
    Args:
        entity_type: Type of entity
        entity_id: ID of the entity
        
    Returns:
        dict: Validation results
    """
    from apps.entities.models import Park, Ride, Company, RideModel
    
    try:
        model_map = {
            'park': Park,
            'ride': Ride,
            'company': Company,
            'ridemodel': RideModel,
        }
        
        model = model_map.get(entity_type.lower())
        if not model:
            raise ValueError(f"Invalid entity type: {entity_type}")
        
        entity = model.objects.get(id=entity_id)
        
        issues = []
        
        # Check for missing required fields
        if not entity.name or entity.name.strip() == '':
            issues.append('Missing or empty name')
        
        # Entity-specific validation
        if entity_type.lower() == 'park' and not entity.country:
            issues.append('Missing country')
        
        if entity_type.lower() == 'ride' and not entity.park:
            issues.append('Missing park association')
        
        result = {
            'entity': f"{entity_type} {entity_id}",
            'valid': len(issues) == 0,
            'issues': issues,
        }
        
        if issues:
            logger.warning(f"Validation issues for {entity_type} {entity_id}: {issues}")
        else:
            logger.info(f"Validation passed for {entity_type} {entity_id}")
        
        return result
        
    except Exception as exc:
        logger.error(f"Error validating {entity_type} {entity_id}: {str(exc)}")
        raise self.retry(exc=exc, countdown=300)
