"""Send job alert emails to qualified paid subscribers when a job is posted."""
from django.conf import settings
from django.db.models import Q
from django.utils import timezone

from accounts.models import User
from subscriptions.models import SeekerSubscription

from .matching import compute_seeker_job_match
from .models import JobAlertLog, JobApplication
from .notifications import notify_seeker_job_alert


def _eligible_subscribers():
    now = timezone.now()
    return (
        SeekerSubscription.objects.filter(
            is_active=True,
            plan__slug=settings.SEEKER_PLUS_PLAN_SLUG,
            plan__is_active=True,
            user__role=User.Role.SEEKER,
        )
        .exclude(user__email='')
        .filter(Q(expires_at__isnull=True) | Q(expires_at__gt=now))
        .select_related('user', 'user__seeker_profile', 'plan')
    )


def dispatch_job_alerts(job):
    """
    Email qualified Professional Plus (K20) subscribers about a newly posted job.
    Returns the number of alerts sent.
    """
    if not job.is_active:
        return 0

    min_score = settings.JOB_ALERT_MIN_MATCH_SCORE
    sent = 0

    already_applied = set(
        JobApplication.objects.filter(job=job).values_list('applicant_id', flat=True)
    )
    already_alerted = set(
        JobAlertLog.objects.filter(job=job).values_list('recipient_id', flat=True)
    )

    for subscription in _eligible_subscribers():
        user = subscription.user
        if user.pk in already_applied or user.pk in already_alerted:
            continue

        profile = getattr(user, 'seeker_profile', None)
        if not profile:
            continue

        match_score = compute_seeker_job_match(profile, job)
        if match_score < min_score:
            continue

        if notify_seeker_job_alert(user, profile, job, match_score):
            JobAlertLog.objects.create(
                job=job,
                recipient=user,
                match_score=match_score,
            )
            sent += 1
            already_alerted.add(user.pk)

    return sent
