"""
Management command to migrate UserActivity data to the new Activity model.
"""
from django.core.management.base import BaseCommand
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.db.utils import IntegrityError

from apps.accounts.models import User
from apps.activities.models import Activity, ActivityCategory


class Command(BaseCommand):
    help = 'Migrate UserActivity data to the new Activity model'

    def add_arguments(self, parser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Run in dry-run mode without making changes',
        )
        parser.add_argument(
            '--batch-size',
            type=int,
            default=1000,
            help='Batch size for processing records',
        )

    def handle(self, *args, **options):
        dry_run = options['dry_run']
        batch_size = options['batch_size']

        if dry_run:
            self.stdout.write(
                self.style.WARNING('Running in DRY-RUN mode - no changes will be made')
            )

        # Check if UserActivity model exists
        try:
            from apps.accounts.models import UserActivity
        except ImportError:
            self.stdout.write(
                self.style.ERROR('UserActivity model not found. Migration may have already been completed.')
            )
            return

        # Create default category for migrated activities
        auth_category, created = ActivityCategory.objects.get_or_create(
            code='authentication',
            defaults={
                'name': 'Authentication',
                'description': 'User authentication and account activities',
                'color': '#28a745',
                'icon': 'fas fa-sign-in-alt',
                'is_system': True
            }
        )

        if created:
            self.stdout.write(
                self.style.SUCCESS(f'Created authentication category: {auth_category}')
            )

        # Get all UserActivity records
        user_activities = UserActivity.objects.all().order_by('created_at')
        total_count = user_activities.count()

        self.stdout.write(f'Found {total_count} UserActivity records to migrate')

        if total_count == 0:
            self.stdout.write(self.style.WARNING('No UserActivity records found to migrate'))
            return

        if dry_run:
            self.stdout.write(
                self.style.SUCCESS(f'Would migrate {total_count} UserActivity records')
            )
            return

        # Process in batches
        migrated_count = 0
        error_count = 0

        with transaction.atomic():
            for i in range(0, total_count, batch_size):
                batch = user_activities[i:i + batch_size]
                
                for user_activity in batch:
                    try:
                        # Map UserActivity fields to Activity fields
                        activity_data = {
                            'user': user_activity.user,
                            'action': self.map_action(user_activity.action),
                            'description': self.generate_description(user_activity),
                            'category': auth_category,
                            'ip_address': user_activity.ip_address,
                            'user_agent': user_activity.user_agent,
                            'is_successful': True,  # Assume all old activities were successful
                            'metadata': user_activity.details or {},
                            'created_at': user_activity.created_at,
                            'updated_at': user_activity.updated_at,
                        }

                        # Handle content_type and object_id
                        if user_activity.object_type and user_activity.object_id:
                            try:
                                # Try to get the ContentType for the object
                                app_label, model_name = user_activity.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'] = user_activity.object_id
                            except (ValueError, ContentType.DoesNotExist):
                                # If we can't find the ContentType, store in metadata
                                activity_data['metadata'].update({
                                    'original_object_type': user_activity.object_type,
                                    'original_object_id': user_activity.object_id,
                                    'original_object_repr': user_activity.object_repr,
                                })

                        # Create the Activity record
                        Activity.objects.create(**activity_data)
                        migrated_count += 1

                        if migrated_count % 100 == 0:
                            self.stdout.write(f'Migrated {migrated_count}/{total_count} records...')

                    except IntegrityError as e:
                        error_count += 1
                        self.stdout.write(
                            self.style.ERROR(f'Error migrating UserActivity {user_activity.id}: {e}')
                        )
                    except Exception as e:
                        error_count += 1
                        self.stdout.write(
                            self.style.ERROR(f'Unexpected error migrating UserActivity {user_activity.id}: {e}')
                        )

        self.stdout.write(
            self.style.SUCCESS(f'Successfully migrated {migrated_count} UserActivity records')
        )
        
        if error_count > 0:
            self.stdout.write(
                self.style.ERROR(f'Failed to migrate {error_count} records')
            )

    def map_action(self, old_action):
        """Map old UserActivity action to new Activity action."""
        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',
        }
        return action_mapping.get(old_action, old_action.upper())

    def generate_description(self, user_activity):
        """Generate a human-readable description for the activity."""
        user_str = user_activity.user.email if user_activity.user else 'System'
        action_str = user_activity.action.replace('_', ' ').title()
        
        if user_activity.object_repr:
            return f"{user_str} - {action_str}: {user_activity.object_repr}"
        else:
            return f"{user_str} - {action_str}"
