"""
Management command to expire stale claims on submissions.

This command can be run manually or via cron as an alternative to the Celery
scheduled task when Celery is not available.

Usage:
    python manage.py expire_stale_claims
    python manage.py expire_stale_claims --minutes=10  # Custom timeout
"""

from django.core.management.base import BaseCommand

from apps.moderation.tasks import expire_stale_claims, DEFAULT_LOCK_DURATION_MINUTES


class Command(BaseCommand):
    help = "Release stale claims on submissions that have exceeded the lock timeout"

    def add_arguments(self, parser):
        parser.add_argument(
            "--minutes",
            type=int,
            default=DEFAULT_LOCK_DURATION_MINUTES,
            help=f"Minutes after which a claim is considered stale (default: {DEFAULT_LOCK_DURATION_MINUTES})",
        )
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Show what would be released without actually releasing",
        )

    def handle(self, *args, **options):
        from datetime import timedelta
        from django.utils import timezone
        from apps.moderation.models import EditSubmission, PhotoSubmission

        minutes = options["minutes"]
        dry_run = options["dry_run"]
        cutoff_time = timezone.now() - timedelta(minutes=minutes)

        self.stdout.write(f"Looking for claims older than {minutes} minutes...")
        self.stdout.write(f"Cutoff time: {cutoff_time.isoformat()}")

        # Find stale claims
        stale_edit = EditSubmission.objects.filter(
            status="CLAIMED",
            claimed_at__lt=cutoff_time,
        ).select_related("claimed_by")

        stale_photo = PhotoSubmission.objects.filter(
            status="CLAIMED",
            claimed_at__lt=cutoff_time,
        ).select_related("claimed_by")

        stale_edit_count = stale_edit.count()
        stale_photo_count = stale_photo.count()

        if stale_edit_count == 0 and stale_photo_count == 0:
            self.stdout.write(self.style.SUCCESS("No stale claims found."))
            return

        self.stdout.write(f"Found {stale_edit_count} stale EditSubmission claims:")
        for sub in stale_edit:
            self.stdout.write(
                f"  - ID {sub.id}: claimed by {sub.claimed_by} at {sub.claimed_at}"
            )

        self.stdout.write(f"Found {stale_photo_count} stale PhotoSubmission claims:")
        for sub in stale_photo:
            self.stdout.write(
                f"  - ID {sub.id}: claimed by {sub.claimed_by} at {sub.claimed_at}"
            )

        if dry_run:
            self.stdout.write(self.style.WARNING("\n--dry-run: No changes made."))
            return

        # Run the actual expiration task
        result = expire_stale_claims(lock_duration_minutes=minutes)

        self.stdout.write(self.style.SUCCESS("\nExpiration complete:"))
        self.stdout.write(
            f"  EditSubmissions: {result['edit_submissions']['released']} released, "
            f"{result['edit_submissions']['failed']} failed"
        )
        self.stdout.write(
            f"  PhotoSubmissions: {result['photo_submissions']['released']} released, "
            f"{result['photo_submissions']['failed']} failed"
        )

        if result["failures"]:
            self.stdout.write(self.style.ERROR("\nFailures:"))
            for failure in result["failures"]:
                self.stdout.write(f"  - {failure}")
