from datetime import timedelta
from django.conf import settings
from django.core.mail import send_mail
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils import timezone
from users.models import AccountEmail


class Command(BaseCommand):
    help = "Deliver pending account emails. Run once per minute; SQLite needs a single worker."

    def add_arguments(self, parser):
        parser.add_argument("--limit", type=int, default=100)

    def handle(self, *args, **options):
        if options["limit"] < 1:
            raise CommandError("--limit must be positive")
        now = timezone.now()
        AccountEmail.objects.filter(expires_at__lte=now).delete()
        ids = list(AccountEmail.objects.filter(sent_at__isnull=True, attempts__lt=5,
                    next_attempt_at__lte=now).order_by("id").values_list("id", flat=True)[:options["limit"]])
        sent = failed = 0
        for pk in ids:
            with transaction.atomic():
                message = AccountEmail.objects.select_for_update().filter(pk=pk, sent_at__isnull=True,
                    next_attempt_at__lte=timezone.now(), expires_at__gt=timezone.now(), attempts__lt=5).first()
                if message is None:
                    continue
                message.attempts += 1
                # The console backend emits MIME (often quoted-printable). Copying its raw
                # text can turn `uid=` and `token=` into `uid=3D` / `token=3D`.
                # Only for local DEBUG console mail, show the exact *unencoded* link.
                console_preview = (
                    settings.DEBUG
                    and settings.MAILERS.get("default", {}).get("BACKEND")
                    == "django.core.mail.backends.console.EmailBackend"
                    and message.subject == "FTG: verify-email"
                )
                if console_preview:
                    prefix = settings.ACCOUNT_FRONTEND_URL.rstrip("/") + "/verify-email?"
                    for line in message.body.splitlines():
                        if line.startswith(prefix):
                            self.stdout.write("FTG DEV VERIFICATION LINK (COPY THIS LINE, KEEP PRIVATE):")
                            self.stdout.write(line)
                            break
                try:
                    count = send_mail(message.subject, message.body, settings.DEFAULT_FROM_EMAIL,
                                      [message.recipient], using="default")
                    if count != 1:
                        raise RuntimeError("Email backend did not accept the message.")
                except Exception as exc:
                    failed += 1
                    message.next_attempt_at = timezone.now() + timedelta(minutes=2 ** message.attempts)
                    self.stderr.write(f"Delivery {pk} failed ({type(exc).__name__}); retry scheduled.")
                else:
                    sent += 1
                    message.sent_at = timezone.now()
                    message.body = ""
                message.save(update_fields=["attempts", "next_attempt_at", "sent_at", "body"])
        self.stdout.write(f"Sent: {sent}; failed: {failed}")
