from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticated
from .serializers import ExerciseSerializer, ExerciseListSerializer
from .models import Exercise
import requests
import json
from config.authentication import JWTAuthenticationWithUserCheck, IsAuthenticatedAndOwner
from utils.stringifiers import markdownToQuilldelta

class ExerciseListView(APIView):
    authentication_classes = [JWTAuthenticationWithUserCheck]
    permission_classes = [IsAuthenticatedAndOwner]

    def get(self, request):
        exercises = Exercise.objects.filter(user=request.user.publicIdentifier)
        serializer = ExerciseListSerializer(exercises, many=True)
        return Response(serializer.data)

    def post(self, request):
        data = request.data
        data['user'] = str(request.user.publicIdentifier)
        serializer = ExerciseSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ExerciseDetailView(APIView):
    authentication_classes = [JWTAuthenticationWithUserCheck]
    permission_classes = [IsAuthenticatedAndOwner]

    @staticmethod
    def get_object(pid, request):
        try:
            return Exercise.objects.get(publicIdentifier=pid, user=request.user.publicIdentifier)
        except Exercise.DoesNotExist:
            raise Http404

    def get(self, request, pid):
        exercise = self.get_object(pid, request) # c'est une instance de la classe Flashcard
        serializer = ExerciseSerializer(exercise) # c'est une instance du serializer, dont l'attribut data contient un dictionnaire python
        return Response(serializer.data)

    def put(self, request, pid):
        exercise = self.get_object(pid, request) # On récupère la flashcard à modifier
        serializer = ExerciseSerializer(exercise, data=request.data) # On remplace avec les nouvelles données
        if serializer.is_valid():
            serializer.save() # Si tout est valide, on sauvegarde les nouvelles données
            return Response(serializer.data)
        return Response(serializer.errors,
                        status=status.HTTP_400_BAD_REQUEST) # Sinon, on ne sauvegarde pas et on renvoit une erreur

    def delete(self, request, pid):
        exercise = self.get_object(pid, request)
        exercise.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

from utils.mistral_api import call_mistral_api
from utils.parsing import extract_text

class CorrectExercise(APIView):
    authentication_classes = [JWTAuthenticationWithUserCheck]
    permission_classes = [IsAuthenticatedAndOwner]

    def post(self, request):

        if not 'instructions' in request.data or not 'visibleAnswer' in request.data or not 'userResponse' in request.data:
            return Response({'error': 'Données invalides'}, status=status.HTTP_400_BAD_REQUEST)

        content = "Sujet : " + extract_text(request.data['instructions'])
        content += "\n\n" + "Réponse : " + extract_text(request.data['visibleAnswer'])
        content += "\n\n" + "Réponse de l'étudiant : " + extract_text(request.data['userResponse'])
        
        response, error = call_mistral_api(
            user=request.user,
            content=content,
            agent_id="ag:65468023:20250421:teacher-comment:bed263db",
            max_tokens=240,
            response_format={"type": "json_object"}
        )

        # Rajouter quelque chose qui vérifie les clés et rajoutent les bonnes clés si besoin
        # + rajouter la gestion de la langue

        if not error:
            return Response(response, status=status.HTTP_200_OK)
        else:
            return Response({'error': response}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        # except Exception as e:
        #     return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# Lorsque l'utilisateur réussi un exercice, l'exercice est marqué comme réussi
# C'est l'utilisateur qui clique sur un bouton pour dire "Je maitrise cet exercice" ou "Revoir cet exercice plus tard"
# Si l'utilisateur maitrise tout les exercices qui sont proposés, on lui affiche un bouton lui proposant de générer un nouvel exercice
# (A rapidement changer par quelque chose d'autre : je voudrais pouvoir suivre ce que font les gens, et leur proposer l'exercice le plus approprié étant donné leur niveau)
# Il suffirait d'avoir un niveau de difficultée pour l'exercice, d'associer chaque exercice à une notion (les flashcards) et de considérer le niveau de maitrise d'un cours par notion. 
# Lorsque l'utilisateur maitrise au niveau 1 une notion, le prochain exercice généré sera de niveau 2, ect...
