"""
Management command to generate due recurring support payments.
This command should be run daily via cron or similar scheduling system.
"""

import logging
from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils import timezone

from stiftung.models import UnterstuetzungWiederkehrend

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = "Generate due recurring support payments"

    def add_arguments(self, parser):
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Show what would be generated without actually creating payments",
        )
        parser.add_argument(
            "--days-ahead",
            type=int,
            default=0,
            help="Generate payments that are due within this many days (default: 0 = only today)",
        )

    def handle(self, *args, **options):
        dry_run = options["dry_run"]
        days_ahead = options["days_ahead"]

        heute = timezone.now().date()
        cutoff_date = heute + timedelta(days=days_ahead)

        self.stdout.write(
            self.style.SUCCESS(
                f'Checking for recurring payments due up to {cutoff_date.strftime("%d.%m.%Y")}...'
            )
        )

        if dry_run:
            self.stdout.write(
                self.style.WARNING("DRY RUN MODE - No payments will be created")
            )

        # Get all active recurring payment templates that are due
        templates = UnterstuetzungWiederkehrend.objects.filter(
            aktiv=True, naechste_generierung__lte=cutoff_date
        ).select_related("destinataer", "konto")

        generated_count = 0
        error_count = 0

        for template in templates:
            try:
                if dry_run:
                    self.stdout.write(
                        f"Would generate: {template.destinataer.get_full_name()} - "
                        f'€{template.betrag} due {template.naechste_generierung.strftime("%d.%m.%Y")}'
                    )
                    generated_count += 1
                else:
                    # Actually generate the payment
                    neue_zahlung = template.generiere_naechste_zahlung()
                    if neue_zahlung:
                        self.stdout.write(
                            self.style.SUCCESS(
                                f"Generated: {neue_zahlung.destinataer.get_full_name()} - "
                                f'€{neue_zahlung.betrag} due {neue_zahlung.faellig_am.strftime("%d.%m.%Y")}'
                            )
                        )
                        generated_count += 1
                        logger.info(f"Generated recurring payment: {neue_zahlung.pk}")
                    else:
                        self.stdout.write(
                            self.style.WARNING(
                                f"No payment generated for {template.destinataer.get_full_name()} "
                                f"(may have reached end date or not yet due)"
                            )
                        )
            except Exception as e:
                error_count += 1
                self.stdout.write(
                    self.style.ERROR(
                        f"Error generating payment for {template.destinataer.get_full_name()}: {str(e)}"
                    )
                )
                logger.error(
                    f"Error generating recurring payment for template {template.pk}: {str(e)}"
                )

        # Summary
        self.stdout.write("\n" + "=" * 50)
        if dry_run:
            self.stdout.write(
                self.style.SUCCESS(
                    f"DRY RUN COMPLETE: {generated_count} payments would be generated"
                )
            )
        else:
            self.stdout.write(
                self.style.SUCCESS(
                    f"GENERATION COMPLETE: {generated_count} payments generated"
                )
            )

        if error_count > 0:
            self.stdout.write(self.style.ERROR(f"{error_count} errors encountered"))

        # Also check for overdue payments and report them
        from stiftung.models import DestinataerUnterstuetzung

        overdue_payments = DestinataerUnterstuetzung.objects.filter(
            faellig_am__lt=heute, status__in=["geplant", "faellig"]
        ).select_related("destinataer")

        if overdue_payments.exists():
            self.stdout.write("\n" + "=" * 50)
            self.stdout.write(
                self.style.WARNING(
                    f"WARNING: {overdue_payments.count()} overdue payments found:"
                )
            )
            for payment in overdue_payments[:10]:  # Limit to first 10
                days_overdue = (heute - payment.faellig_am).days
                self.stdout.write(
                    f"  - {payment.destinataer.get_full_name()}: €{payment.betrag} "
                    f"({days_overdue} days overdue)"
                )
            if overdue_payments.count() > 10:
                self.stdout.write(f"  ... and {overdue_payments.count() - 10} more")
