"""
Django management command for property description data extraction.

Usage:
    python manage.py extract_description_data --all
    python manage.py extract_description_data --ids 1 2 3
    python manage.py extract_description_data --missing-only
    python manage.py extract_description_data --source "otodom"
"""

from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q
from extractly.models import AdsManual
from manual_agregator.description_extrator.django_integration import PropertyExtractorService


class Command(BaseCommand):
    help = 'Extract property data from descriptions using description_extrator'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--all',
            action='store_true',
            help='Process all AdsManual records'
        )
        parser.add_argument(
            '--ids',
            nargs='+',
            type=int,
            help='Specific AdsManual IDs to process'
        )
        parser.add_argument(
            '--missing-only',
            action='store_true',
            help='Only process records with missing room data'
        )
        parser.add_argument(
            '--source',
            type=str,
            help='Filter by source name (e.g., "otodom", "gratka")'
        )
        parser.add_argument(
            '--overwrite',
            action='store_true',
            help='Overwrite existing data (default: only fill empty fields)'
        )
        parser.add_argument(
            '--batch-size',
            type=int,
            default=100,
            help='Batch size for processing (default: 100)'
        )
        parser.add_argument(
            '--limit',
            type=int,
            help='Limit number of records to process'
        )
    
    def handle(self, *args, **options):
        service = PropertyExtractorService()
        
        # Build queryset
        queryset = AdsManual.objects.all()
        
        # Apply filters
        if options['ids']:
            queryset = queryset.filter(id__in=options['ids'])
            self.stdout.write(f"Processing {len(options['ids'])} specific records...")
        
        elif options['missing_only']:
            queryset = queryset.filter(
                Q(rooms__isnull=True) | 
                Q(square_footage__isnull=True) |
                Q(city__isnull=True)
            )
            self.stdout.write(f"Processing records with missing data...")
        
        elif options['all']:
            self.stdout.write(f"Processing all records...")
        
        else:
            raise CommandError('Please specify --all, --ids, or --missing-only')
        
        # Filter by source if specified
        if options['source']:
            # Try to filter by network_monitored_page__source__name
            queryset = queryset.filter(
                Q(network_monitored_page__source__name__icontains=options['source']) |
                Q(network_monitored_page__source__title__icontains=options['source'])
            )
            self.stdout.write(f"Filtered by source: {options['source']}")
        
        # Filter out records without descriptions
        queryset = queryset.exclude(
            Q(description__isnull=True) | 
            Q(description__exact='')
        )
        
        total = queryset.count()
        
        if total == 0:
            self.stdout.write(self.style.WARNING("No records to process"))
            return
        
        # Apply limit if specified
        if options['limit']:
            queryset = queryset[:options['limit']]
            self.stdout.write(f"Limited to {options['limit']} records")
        
        self.stdout.write(f"\nTotal records to process: {total}")
        self.stdout.write(f"Batch size: {options['batch_size']}")
        self.stdout.write(f"Overwrite mode: {'ON' if options['overwrite'] else 'OFF'}\n")
        
        # Progress callback
        processed = [0]  # Use list to allow modification in nested function
        
        def progress(current, total_count):
            processed[0] = current
            percent = (current / total_count * 100) if total_count > 0 else 0
            self.stdout.write(
                f"\rProgress: {current}/{total_count} ({percent:.1f}%)",
                ending=''
            )
            self.stdout.flush()
        
        # Execute extraction
        try:
            stats = service.bulk_extract(
                queryset,
                batch_size=options['batch_size'],
                overwrite=options['overwrite'],
                progress_callback=progress
            )
            
            # Print results
            self.stdout.write("\n\n" + "="*70)
            self.stdout.write(self.style.SUCCESS("✓ Extraction Complete!"))
            self.stdout.write("="*70)
            self.stdout.write(f"  Total records:     {stats['total']}")
            self.stdout.write(self.style.SUCCESS(f"  ✓ Successful:      {stats['successful']}"))
            self.stdout.write(self.style.ERROR(f"  ✗ Failed:          {stats['failed']}"))
            self.stdout.write(self.style.WARNING(f"  ⊘ Skipped:         {stats['skipped']}"))
            
            if stats['successful'] > 0:
                success_rate = (stats['successful'] / stats['total'] * 100) if stats['total'] > 0 else 0
                self.stdout.write(f"\n  Success rate:      {success_rate:.1f}%")
            
            self.stdout.write("="*70 + "\n")
            
        except KeyboardInterrupt:
            self.stdout.write("\n\n" + self.style.WARNING("⚠ Interrupted by user"))
            self.stdout.write(f"Processed {processed[0]} records before interruption")
        
        except Exception as e:
            self.stdout.write("\n\n" + self.style.ERROR(f"✗ Error: {str(e)}"))
            raise
