"""
Helper functions for the activities app to maintain backward compatibility
with the old UserActivity model usage patterns.
"""
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.db import IntegrityError
from .models import Activity, ActivityCategory


def get_or_create_category(code, name, description, color, icon, is_system=True):
    """
    Helper function to get or create a category safely.
    """
    try:
        return ActivityCategory.objects.get(code=code)
    except ActivityCategory.DoesNotExist:
        try:
            return ActivityCategory.objects.create(
                code=code,
                name=name,
                description=description,
                color=color,
                icon=icon,
                is_system=is_system
            )
        except IntegrityError:
            # If there's a race condition, try to get it again
            return ActivityCategory.objects.get(code=code)


def log_user_activity(user, action, object_type=None, object_id=None, object_repr=None, 
                     details=None, ip_address=None, user_agent=None, request=None):
    """
    Helper function to maintain backward compatibility with old UserActivity.objects.create() calls.
    
    This function maps the old UserActivity parameters to the new Activity.log_activity() method.
    """
    # Map old action names to new ACTION_CHOICES
    action_mapping = {
        'login': 'LOGIN',
        'logout': 'LOGOUT',
        'password_change': 'PASSWORD_CHANGE',
        'password_reset': 'PASSWORD_RESET',
        'account_verified': 'ACCOUNT_VERIFIED',
        'profile_update': 'UPDATE',
        'create': 'CREATE',
        'read': 'READ',
        'update': 'UPDATE',
        'delete': 'DELETE',
        'export': 'EXPORT',
        'import': 'IMPORT',
        'admin': 'ADMIN',
    }
    
    mapped_action = action_mapping.get(action, action.upper())
    
    # Generate description
    user_str = user.email if user else 'System'
    action_str = action.replace('_', ' ').title()
    
    if object_repr:
        description = f"{user_str} - {action_str}: {object_repr}"
    else:
        description = f"{user_str} - {action_str}"
    
    # Get or create appropriate category
    if action in ['login', 'logout', 'password_change', 'password_reset', 'account_verified']:
        category = get_or_create_category(
            code='auth',
            name='Authentication',
            description='User authentication and account activities',
            color='#28a745',
            icon='fas fa-sign-in-alt',
            is_system=True
        )
    elif action in ['profile_update', 'update']:
        category = get_or_create_category(
            code='admin',
            name='User Management',
            description='User profile and account management activities',
            color='#007bff',
            icon='fas fa-users',
            is_system=True
        )
    else:
        category = get_or_create_category(
            code='admin',
            name='General',
            description='General system activities',
            color='#6c757d',
            icon='fas fa-cog',
            is_system=True
        )
    
    # Prepare activity data
    activity_data = {
        'user': user,
        'action': mapped_action,
        'description': description,
        'category': category,
        'ip_address': ip_address,
        'user_agent': user_agent,
        'metadata': details or {},
        'is_successful': True,
    }
    
    # Handle content object
    if object_type and object_id:
        try:
            # Try to parse object_type as app_label.model_name
            if '.' in object_type:
                app_label, model_name = object_type.lower().split('.')
                content_type = ContentType.objects.get(app_label=app_label, model=model_name)
                activity_data['content_type'] = content_type
                activity_data['object_id'] = object_id
            else:
                # Store in metadata if we can't parse it
                activity_data['metadata'].update({
                    'original_object_type': object_type,
                    'original_object_id': object_id,
                    'original_object_repr': object_repr,
                })
        except (ContentType.DoesNotExist, ValueError):
            # Store in metadata if ContentType doesn't exist
            activity_data['metadata'].update({
                'original_object_type': object_type,
                'original_object_id': object_id,
                'original_object_repr': object_repr,
            })
    
    # Use the Activity.log_activity method
    if request:
        return Activity.log_activity(request=request, **activity_data)
    else:
        return Activity.log_activity(**activity_data)


def get_user_activities(user, limit=None):
    """
    Get user activities with backward compatibility for old UserActivity queries.
    """
    activities = Activity.objects.filter(user=user).order_by('-created_at')
    
    if limit:
        activities = activities[:limit]
    
    return activities


def get_recent_activities(days=7, limit=None):
    """
    Get recent activities for all users.
    """
    cutoff_date = timezone.now() - timezone.timedelta(days=days)
    activities = Activity.objects.filter(
        created_at__gte=cutoff_date
    ).select_related('user', 'category').order_by('-created_at')
    
    if limit:
        activities = activities[:limit]
    
    return activities
