# -*- coding: utf-8 -*-
"""
Management command to clean up old activity records.

Usage:
    python manage.py cleanup_activities --days 90 --dry-run
    python manage.py cleanup_activities --days 180 --archive
    python manage.py cleanup_activities --days 30 --delete
"""

from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from django.db import transaction
from datetime import timedelta
import logging

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'Clean up old activity records'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--days',
            type=int,
            default=90,
            help='Number of days to keep (default: 90)'
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be cleaned without actually cleaning'
        )
        parser.add_argument(
            '--delete',
            action='store_true',
            help='Actually delete the activities'
        )
        parser.add_argument(
            '--archive',
            action='store_true',
            help='Archive activities before deletion'
        )
        parser.add_argument(
            '--batch-size',
            type=int,
            default=1000,
            help='Number of activities to process in each batch (default: 1000)'
        )
        parser.add_argument(
            '--format',
            choices=['csv', 'json'],
            default='json',
            help='Archive format (default: json)'
        )
    
    def handle(self, *args, **options):
        days = options['days']
        dry_run = options['dry_run']
        delete = options['delete']
        archive = options['archive']
        batch_size = options['batch_size']
        archive_format = options['format']
        
        if not dry_run and not delete:
            raise CommandError(
                'You must specify either --dry-run or --delete'
            )
        
        if dry_run and delete:
            raise CommandError(
                'Cannot specify both --dry-run and --delete'
            )
        
        # Import here to avoid circular imports
        from apps.activities.models import Activity
        from apps.activities.services import ActivityCleanupService
        
        # Calculate cutoff date
        cutoff_date = timezone.now() - timedelta(days=days)
        
        self.stdout.write(
            self.style.SUCCESS(
                f'Looking for activities older than: {cutoff_date.strftime("%Y-%m-%d %H:%M:%S")}'
            )
        )
        
        # Get activities to process
        old_activities = Activity.objects.filter(
            timestamp__lt=cutoff_date
        )
        
        total_count = old_activities.count()
        
        if total_count == 0:
            self.stdout.write(
                self.style.SUCCESS('No old activities found.')
            )
            return
        
        self.stdout.write(
            self.style.WARNING(
                f'Found {total_count} activities older than {days} days.'
            )
        )
        
        # Show sample activities
        sample_activities = old_activities.select_related('user')[:5]
        self.stdout.write('\nSample activities:')
        for activity in sample_activities:
            self.stdout.write(
                f'  - {activity.user.email}: {activity.action} '
                f'({activity.timestamp.strftime("%Y-%m-%d %H:%M")})')
        
        if total_count > 5:
            self.stdout.write(f'  ... and {total_count - 5} more activities')
        
        # Dry run mode
        if dry_run:
            self.stdout.write(
                self.style.SUCCESS(
                    f'\nDRY RUN: Would clean up {total_count} activities.'
                )
            )
            if archive:
                self.stdout.write(
                    self.style.SUCCESS(
                        f'Would archive to {archive_format.upper()} format before deletion.'
                    )
                )
            return
        
        # Confirm deletion
        if not self._confirm_cleanup(total_count, archive):
            self.stdout.write(self.style.ERROR('Operation cancelled.'))
            return
        
        try:
            # Archive if requested
            if archive:
                self.stdout.write('Archiving old activities...')
                archive_path = ActivityCleanupService.archive_activities(
                    days=days,
                    archive_format=archive_format
                )
                
                if archive_path:
                    self.stdout.write(
                        self.style.SUCCESS(
                            f'Activities archived to: {archive_path}'
                        )
                    )
                else:
                    self.stdout.write(
                        self.style.WARNING('No activities were archived.')
                    )
            
            # Clean up activities
            self.stdout.write('Cleaning up old activities...')
            deleted_count = ActivityCleanupService.cleanup_old_activities(
                days=days,
                batch_size=batch_size
            )
            
            self.stdout.write(
                self.style.SUCCESS(
                    f'\nSuccessfully cleaned up {deleted_count} old activities.'
                )
            )
            
            # Log the cleanup
            logger.info(
                f'Activity cleanup completed: {deleted_count} activities deleted '
                f'(older than {days} days)'
            )
            
        except Exception as e:
            logger.error(f'Error during activity cleanup: {str(e)}')
            raise CommandError(f'Error during cleanup: {str(e)}')
    
    def _confirm_cleanup(self, count, archive):
        """Confirm cleanup with user input."""
        action = 'archive and delete' if archive else 'delete'
        
        self.stdout.write(
            self.style.WARNING(
                f'\nThis will {action} {count} old activities.'
            )
        )
        
        if archive:
            self.stdout.write(
                self.style.SUCCESS(
                    'Activities will be archived before deletion.'
                )
            )
        else:
            self.stdout.write(
                self.style.ERROR(
                    'Activities will be permanently deleted without archiving.'
                )
            )
        
        response = input('Are you sure you want to continue? (yes/no): ')
        return response.lower() in ['yes', 'y']