"""
Django management command to generate daily portfolio snapshots

This command can be run manually or scheduled via cron to automatically
generate portfolio snapshots for all portfolio managers.

Usage:
    python manage.py generate_portfolio_snapshots
    python manage.py generate_portfolio_snapshots --date 2024-01-15
    python manage.py generate_portfolio_snapshots --manager-id <uuid>
"""

from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from datetime import datetime, date
import logging

from users.portfolio_snapshot_service import PortfolioSnapshotService
from users.models import CustomUser

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'Generate daily portfolio snapshots for portfolio managers'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--date',
            type=str,
            help='Date to generate snapshots for (YYYY-MM-DD format). Defaults to today.'
        )
        
        parser.add_argument(
            '--manager-id',
            type=str,
            help='Generate snapshot for specific manager ID only'
        )
        
        parser.add_argument(
            '--force',
            action='store_true',
            help='Force regeneration of existing snapshots'
        )
        
        parser.add_argument(
            '--send-alerts',
            action='store_true',
            default=True,
            help='Send performance alerts (default: True)'
        )
        
        parser.add_argument(
            '--verbose',
            action='store_true',
            help='Enable verbose output'
        )
    
    def handle(self, *args, **options):
        # Set up logging level
        if options['verbose']:
            logging.basicConfig(level=logging.DEBUG)
        else:
            logging.basicConfig(level=logging.INFO)
        
        # Parse target date
        target_date = None
        if options['date']:
            try:
                target_date = datetime.strptime(options['date'], '%Y-%m-%d').date()
            except ValueError:
                raise CommandError(f"Invalid date format: {options['date']}. Use YYYY-MM-DD format.")
        else:
            target_date = timezone.now().date()
        
        self.stdout.write(f"Generating portfolio snapshots for {target_date}")
        
        # Initialize service
        snapshot_service = PortfolioSnapshotService()
        
        try:
            if options['manager_id']:
                # Generate snapshot for specific manager
                try:
                    manager = CustomUser.objects.get(
                        id=options['manager_id'],
                        role__in=['loan_officer', 'team_leader'],
                        is_active=True
                    )
                    
                    self.stdout.write(f"Generating snapshot for {manager.get_full_name()}")
                    
                    # Check if snapshot already exists
                    from users.enhanced_permissions_models import PortfolioSnapshot
                    existing_snapshot = PortfolioSnapshot.objects.filter(
                        manager=manager,
                        snapshot_date=target_date
                    ).first()
                    
                    if existing_snapshot and not options['force']:
                        self.stdout.write(
                            self.style.WARNING(
                                f"Snapshot already exists for {manager.get_full_name()} on {target_date}. "
                                "Use --force to regenerate."
                            )
                        )
                        return
                    
                    # Generate single snapshot
                    snapshot_data = snapshot_service._calculate_portfolio_metrics(manager, target_date)
                    
                    if existing_snapshot:
                        # Update existing snapshot
                        for key, value in snapshot_data.items():
                            setattr(existing_snapshot, key, value)
                        existing_snapshot.save()
                        snapshot = existing_snapshot
                        action = "updated"
                    else:
                        # Create new snapshot
                        snapshot = PortfolioSnapshot.objects.create(
                            manager=manager,
                            snapshot_date=target_date,
                            **snapshot_data
                        )
                        action = "created"
                    
                    # Calculate health score
                    health_score = snapshot.get_portfolio_health_score()
                    
                    # Send alerts if enabled
                    if options['send_alerts']:
                        snapshot_service._check_performance_alerts(manager, snapshot, health_score)
                    
                    self.stdout.write(
                        self.style.SUCCESS(
                            f"Successfully {action} snapshot for {manager.get_full_name()} "
                            f"(Health Score: {health_score}%)"
                        )
                    )
                    
                except CustomUser.DoesNotExist:
                    raise CommandError(f"Manager with ID {options['manager_id']} not found or not a portfolio manager")
                
            else:
                # Generate snapshots for all managers
                results = snapshot_service.generate_daily_snapshots(target_date)
                
                if results['success']:
                    self.stdout.write(
                        self.style.SUCCESS(
                            f"Successfully processed {results['managers_processed']} managers:\n"
                            f"  - {results['snapshots_generated']} new snapshots created\n"
                            f"  - {results['snapshots_updated']} existing snapshots updated"
                        )
                    )
                    
                    if results['errors']:
                        self.stdout.write(
                            self.style.WARNING(
                                f"Encountered {len(results['errors'])} errors:"
                            )
                        )
                        for error in results['errors']:
                            self.stdout.write(f"  - {error}")
                else:
                    raise CommandError(f"Snapshot generation failed: {results.get('error', 'Unknown error')}")
        
        except Exception as e:
            logger.error(f"Command execution failed: {e}")
            raise CommandError(f"Failed to generate snapshots: {str(e)}")
        
        self.stdout.write(
            self.style.SUCCESS(
                f"Portfolio snapshot generation completed for {target_date}"
            )
        )
    
    def _format_results_summary(self, results):
        """Format results summary for display"""
        summary = f"""
Portfolio Snapshot Generation Summary
=====================================
Date: {results['date']}
Managers Processed: {results['managers_processed']}
New Snapshots: {results['snapshots_generated']}
Updated Snapshots: {results['snapshots_updated']}
Errors: {len(results['errors'])}
Success: {results['success']}
"""
        
        if results['errors']:
            summary += "\nErrors encountered:\n"
            for error in results['errors']:
                summary += f"  - {error}\n"
        
        return summary