"""
Génération automatique des créneaux à partir des templates.
Semaines courante et à venir (à partir d'aujourd'hui).
"""
from datetime import date, time, timedelta, datetime

from django.utils import timezone

from .models import SlotTemplate, AppointmentSlot


def generate_slots_for_weeks(num_weeks=4, from_date=None):
    """
    Génère les AppointmentSlot pour les prochaines `num_weeks` semaines
    à partir de `from_date` (défaut: aujourd'hui), en utilisant les templates actifs.
    Ne crée pas de doublon (date, start_time) déjà existant.
    """
    from_date = from_date or timezone.localdate()
    end_date = from_date + timedelta(weeks=num_weeks)
    templates = SlotTemplate.objects.filter(is_active=True)
    created_count = 0

    for template in templates:
        # Trouver toutes les dates entre from_date et end_date qui correspondent au weekday
        current = from_date
        while current <= end_date:
            if current.weekday() == template.weekday:
                created_count += _generate_slots_for_day(
                    current,
                    template.start_time,
                    template.end_time,
                    template.slot_duration_minutes,
                    template.is_online,
                    template.meet_link,
                    template.location_notes,
                    template=template,
                )
            current += timedelta(days=1)

    return created_count


def _generate_slots_for_day(
    day,
    start_time,
    end_time,
    duration_minutes,
    is_online,
    meet_link,
    location_notes,
    template=None,
):
    """Pour une date donnée, crée les créneaux entre start_time et end_time par pas de duration_minutes."""
    created = 0
    start_dt = datetime.combine(day, start_time)
    end_dt = datetime.combine(day, end_time)
    delta = timedelta(minutes=duration_minutes)
    slot_start = start_dt

    while slot_start + delta <= end_dt:
        slot_end = slot_start + delta
        st = slot_start.time()
        et = slot_end.time()
        if not AppointmentSlot.objects.filter(date=day, start_time=st).exists():
            AppointmentSlot.objects.create(
                date=day,
                start_time=st,
                end_time=et,
                is_online=is_online,
                meet_link=meet_link or "",
                location_notes=location_notes or "",
                template=template,
            )
            created += 1
        slot_start = slot_end

    return created
