from django.http.response import JsonResponse
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
from dateutil.relativedelta import relativedelta

from .models import Planning, Events, RecursionType

from .serializers import PlanningSerializer, EventsSerializer

from N3wtSchool import bdd
from Subscriptions.util import getCurrentSchoolYear


class PlanningView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        establishment_id = request.GET.get('establishment_id', None)
        planning_mode = request.GET.get('planning_mode', None)
        current_school_year = getCurrentSchoolYear()

        plannings = bdd.getAllObjects(Planning)

        if establishment_id is not None:
            plannings = plannings.filter(establishment=establishment_id)

        # Filtrer en fonction du planning_mode
        if planning_mode == "classSchedule":
            plannings = plannings.filter(
                school_class__isnull=False,
                school_class__school_year=current_school_year,
            )
        elif planning_mode == "planning":
            plannings = plannings.filter(school_class__isnull=True)

        planning_serializer = PlanningSerializer(plannings.distinct(), many=True)
        return JsonResponse(planning_serializer.data, safe=False)

    def post(self, request):
        planning_serializer = PlanningSerializer(data=request.data)
        if planning_serializer.is_valid():
            planning_serializer.save()
            return JsonResponse(planning_serializer.data, status=201)
        return JsonResponse(planning_serializer.errors, status=400)



class PlanningWithIdView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request,id):
        planning = Planning.objects.get(pk=id)
        if planning is None:
            return JsonResponse({"errorMessage":'Le dossier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
        planning_serializer=PlanningSerializer(planning)

        return JsonResponse(planning_serializer.data, safe=False)

    def put(self, request, id):
        try:
            planning = Planning.objects.get(pk=id)
        except Planning.DoesNotExist:
            return JsonResponse({'error': 'Planning not found'}, status=404)

        planning_serializer = PlanningSerializer(planning, data=request.data)
        if planning_serializer.is_valid():
            planning_serializer.save()
            return JsonResponse(planning_serializer.data)
        return JsonResponse(planning_serializer.errors, status=400)

    def delete(self, request, id):
        try:
            planning = Planning.objects.get(pk=id)
        except Planning.DoesNotExist:
            return JsonResponse({'error': 'Planning not found'}, status=404)

        planning.delete()
        return JsonResponse({'message': 'Planning deleted'}, status=204)

class EventsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        establishment_id = request.GET.get('establishment_id', None)
        planning_mode = request.GET.get('planning_mode', None)
        current_school_year = getCurrentSchoolYear()
        filterParams = {}
        plannings=[]
        events = Events.objects.all()
        if establishment_id is not None :
            filterParams['establishment'] = establishment_id
        if planning_mode is not None:
            filterParams['school_class__isnull'] = (planning_mode!="classSchedule")
            if planning_mode == "classSchedule":
                filterParams['school_class__school_year'] = current_school_year
        if filterParams:
            plannings = Planning.objects.filter(**filterParams)
            events = Events.objects.filter(planning__in=plannings)
        events_serializer = EventsSerializer(events, many=True)
        return JsonResponse(events_serializer.data, safe=False)

    def post(self, request):
        events_serializer = EventsSerializer(data=request.data)
        if events_serializer.is_valid():
            event = events_serializer.save()

            # Gérer les événements récurrents
            if event.recursionType != RecursionType.RECURSION_NONE:
                self.create_recurring_events(event)

            return JsonResponse(events_serializer.data, status=201)
        return JsonResponse(events_serializer.errors, status=400)

    def create_recurring_events(self, event):
        current_start = event.start
        current_end = event.end

        while current_start < event.recursionEnd:
            if event.recursionType == RecursionType.RECURSION_DAILY:
                current_start += relativedelta(days=1)
                current_end += relativedelta(days=1)
            elif event.recursionType == RecursionType.RECURSION_WEEKLY:
                current_start += relativedelta(weeks=1)
                current_end += relativedelta(weeks=1)
            elif event.recursionType == RecursionType.RECURSION_MONTHLY:
                current_start += relativedelta(months=1)
                current_end += relativedelta(months=1)
            else:
                break  # Pour d'autres types de récurrence non gérés

            # Créer une nouvelle occurrence
            Events.objects.create(
                planning=event.planning,
                title=event.title,
                description=event.description,
                start=current_start,
                end=current_end,
                recursionEnd=event.recursionEnd,
                recursionType=event.recursionType,  # Les occurrences ne sont pas récurrentes
                color=event.color,
                location=event.location,
            )

class EventsWithIdView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request, id):
        try:
            event = Events.objects.get(pk=id)
        except Events.DoesNotExist:
            return JsonResponse({'error': 'Event not found'}, status=404)

        events_serializer = EventsSerializer(event, data=request.data)
        if events_serializer.is_valid():
            events_serializer.save()
            return JsonResponse(events_serializer.data)
        return JsonResponse(events_serializer.errors, status=400)

    def delete(self, request, id):
        try:
            event = Events.objects.get(pk=id)
        except Events.DoesNotExist:
            return JsonResponse({'error': 'Event not found'}, status=404)

        event.delete()
        return JsonResponse({'message': 'Event deleted'}, status=200)

class UpcomingEventsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        current_date = timezone.now()
        establishment_id = request.GET.get('establishment_id', None)

        if establishment_id is not None:
            # Filtrer les plannings par establishment_id et sans school_class
            plannings = Planning.objects.filter(establishment=establishment_id, school_class__isnull=True)
            # Filtrer les événements associés à ces plannings et qui sont à venir
            upcoming_events = Events.objects.filter(planning__in=plannings, start__gte=current_date)
        else:
            # Récupérer tous les événements à venir si aucun establishment_id n'est fourni
            # et les plannings ne doivent pas être rattachés à une school_class
            plannings = Planning.objects.filter(school_class__isnull=True)
            upcoming_events = Events.objects.filter(planning__in=plannings, start__gte=current_date)

        events_serializer = EventsSerializer(upcoming_events, many=True)
        return JsonResponse(events_serializer.data, safe=False)