"""Celery task that backfills placeholder emails on a schedule."""

import logging

from celery import shared_task
from django.contrib.auth import get_user_model
from django.db.models import Q

from aa_skip_email.app_settings import AA_SKIP_EMAIL_LIMIT
from aa_skip_email.helpers import make_placeholder_email

logger = logging.getLogger(__name__)

User = get_user_model()


@shared_task(name="aa_skip_email.fill_missing_emails")
def fill_missing_emails(limit: int = AA_SKIP_EMAIL_LIMIT) -> int:
    """
    Fill blank or NULL ``User.email`` with placeholder addresses.

    Processes at most ``limit`` users per invocation. Returns the number
    of rows updated. The save is intentionally non-atomic across the
    batch — partial progress is acceptable because the helper is
    deterministic, so a re-run will resume cleanly.

    ``user.save(update_fields=["email"])`` is intentional: it fires
    ``User.post_save`` so AA-side state recomputation runs on the
    backfilled row. The bulk-update alternative would silence those
    handlers — explicit chunked writes are the right trade-off here.
    """
    qs = (
        User.objects.filter(Q(email__isnull=True) | Q(email=""))
        .order_by("id")
        .only("id", "email")[:limit]
    )
    updated = 0
    for user in qs.iterator(chunk_size=1000):
        username = user.get_username()
        user.email = make_placeholder_email(username, user.id)
        user.save(update_fields=["email"])
        updated += 1
        logger.debug("Filled in missing email for %s", user)
    return updated
