from django.core.management.base import BaseCommand
from django.utils import timezone
from django.db.models import Sum
from loans.models import Loan
from decimal import Decimal
import logging

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'Update loan statuses based on payments and due dates'

    def add_arguments(self, parser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be updated without making changes',
        )
        parser.add_argument(
            '--days-overdue',
            type=int,
            default=30,
            help='Number of days overdue before marking as defaulted (default: 30)',
        )

    def handle(self, *args, **options):
        dry_run = options['dry_run']
        days_overdue_threshold = options['days_overdue']
        
        self.stdout.write(
            self.style.SUCCESS(f'Starting loan status update {"(DRY RUN)" if dry_run else ""}')
        )
        
        # Get all active loans
        active_loans = Loan.objects.filter(status='active')
        
        updated_count = 0
        paid_count = 0
        defaulted_count = 0
        
        for loan in active_loans:
            original_status = loan.status
            
            # Recalculate amount paid from all repayments
            total_paid = loan.repayments.aggregate(
                total=Sum('amount')
            )['total'] or Decimal('0.00')
            
            # Update amount_paid if it's different
            if loan.amount_paid != total_paid:
                if not dry_run:
                    loan.amount_paid = total_paid
                    loan.save(update_fields=['amount_paid'])
                self.stdout.write(
                    f'Updated amount_paid for loan {loan.loan_number}: '
                    f'{loan.amount_paid} -> {total_paid}'
                )
            
            # Check if loan should be marked as paid
            if total_paid >= loan.total_amount:
                if not dry_run:
                    loan.status = 'paid'
                    loan.save(update_fields=['status'])
                paid_count += 1
                self.stdout.write(
                    self.style.SUCCESS(
                        f'Marked loan {loan.loan_number} as PAID '
                        f'(paid: {total_paid}, total: {loan.total_amount})'
                    )
                )
            
            # Check if loan should be marked as defaulted
            elif loan.is_overdue and loan.days_overdue >= days_overdue_threshold:
                if not dry_run:
                    loan.status = 'defaulted'
                    loan.save(update_fields=['status'])
                defaulted_count += 1
                self.stdout.write(
                    self.style.WARNING(
                        f'Marked loan {loan.loan_number} as DEFAULTED '
                        f'({loan.days_overdue} days overdue)'
                    )
                )
            
            if loan.status != original_status:
                updated_count += 1
        
        # Summary
        self.stdout.write(
            self.style.SUCCESS(
                f'\nSummary {"(DRY RUN)" if dry_run else ""}:\n'
                f'- Total loans processed: {active_loans.count()}\n'
                f'- Loans updated: {updated_count}\n'
                f'- Marked as paid: {paid_count}\n'
                f'- Marked as defaulted: {defaulted_count}'
            )
        )
        
        if dry_run:
            self.stdout.write(
                self.style.WARNING(
                    'This was a dry run. Use --no-dry-run to apply changes.'
                )
            )