from collections import Counter
from datetime import timedelta

import structlog
from django.db.models import QuerySet
from django.utils import timezone

from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
from vbv_lernwelt.learnpath.models import Circle
from vbv_lernwelt.notify.services import NotificationService

logger = structlog.get_logger(__name__)

PRESENCE_COURSE_REMINDER_LEAD_TIME = timedelta(weeks=2)


def send_attendance_reminder_notifications():
    """Checks if an attendance course is coming up and sends a reminder to the participants"""
    start = timezone.now()
    end = timezone.now() + PRESENCE_COURSE_REMINDER_LEAD_TIME
    results_counter = Counter()
    attendance_courses = CourseSessionAttendanceCourse.objects.filter(
        due_date__start__lte=end,
        due_date__start__gte=start,
    )

    logger.info(
        "Querying for attendance courses in specified time range",
        start_time=start.isoformat(),
        end_time=end.isoformat(),
        label="attendance_course_reminder_notification_job",
        num_attendance_courses=len(attendance_courses),
    )
    for attendance_course in attendance_courses:
        cs_id = attendance_course.course_session.id
        csu = get_recipients(attendance_course)
        logger.info(
            "Sending attendance course reminder notification",
            start_time=start.isoformat(),
            end_time=end.isoformat(),
            label="attendance_course_reminder_notification_job",
            num_users=len(csu),
            course_session_id=cs_id,
        )
        for user in csu:
            result = NotificationService.send_attendance_course_reminder_notification(
                user.user, attendance_course
            )
            results_counter[result] += 1
    if not attendance_courses:
        logger.info(
            "No attendance courses found",
            label="attendance_course_reminder_notification_job",
        )
    return dict(results_counter)


def get_recipients(
    attendance_course: CourseSessionAttendanceCourse,
) -> QuerySet["CourseSessionUser"]:
    cs_id = attendance_course.course_session.id
    circle_page = attendance_course.learning_content.get_parent_circle()
    circle = Circle.objects.get(page_ptr=circle_page.id)
    members = CourseSessionUser.objects.filter(
        course_session_id=cs_id, role=CourseSessionUser.Role.MEMBER
    )
    experts = CourseSessionUser.objects.filter(
        course_session_id=cs_id, role=CourseSessionUser.Role.EXPERT, expert=circle
    )
    return members | experts
