from course.models import Course
from knowledge.models import Knowledge
from flashcard.models import Flashcard
from exercise.models import Exercise
from user.models import User
from course.serializers import CreateCourseSerializer, CourseSerializer
from knowledge.serializers import KnowledgeSerializer
from flashcard.serializers import FlashcardSerializer
from exercise.serializers import ExerciseSerializer
from course.serializers import PublicCourseSerializer

def copy_course(course, user):
    """
    Copie un cours existant pour un nouvel utilisateur.
    
    Args:
        course (Course): Le cours à copier
        user (User): L'utilisateur qui recevra la copie du cours
        
    Returns:
        Course: L'instance (model) du cours créé
        
    Description:
        Cette fonction prend un cours existant et crée une copie pour un nouvel utilisateur.
        Elle conserve les métadonnées du cours (nom, tags, niveau académique, matière)
        et structure son contenu (knowledges, flashcards, exercises).
    """
    
    # Récupération des données du cours
    course_data = {
        'name': course.name,
        'tags': course.tags,
        'academicLevel': course.academicLevel,
        'subjectStudied': course.subjectStudied,
        'user': str(user.publicIdentifier),
        'copied_from': str(course.publicIdentifier)
    }

    # Récupération des éléments depuis la base de données
    structured_content = []
    for content_id in course.content:
        # Si c'est une flashcard
        if content_id.startswith('#F#'):
            flashcard_id = content_id[3:]  # Enlève le préfixe '#F#'
            flashcard = Flashcard.objects.get(publicIdentifier=flashcard_id)
            structured_content.append({
                'type': 'flashcard',
                'data': {
                    'title': flashcard.title,
                    'question': flashcard.question,
                    'answer': flashcard.answer
                }
            })
        # Si c'est un exercice
        elif content_id.startswith('#E#'):
            exercise_id = content_id[3:]  # Enlève le préfixe '#E#'
            exercise = Exercise.objects.get(publicIdentifier=exercise_id)
            structured_content.append({
                'type': 'exercise',
                'data': {
                    'title': exercise.title,
                    'instructions': exercise.instructions,
                    'visibleAnswer': exercise.visibleAnswer
                }
            })
        else:
            knowledge = Knowledge.objects.get(publicIdentifier=content_id)
            structured_content.append({
                'type': 'text',
                'data': {
                    'title': knowledge.title,
                    'content': knowledge.content,
                    'question': knowledge.question,
                    'comment': knowledge.comment
                }
            })
    print("[copy_course] structured_content: ", structured_content)
    print("[copy_course] course_data: ", course_data)
    
    return create_course_with_content(course_data, structured_content)



def create_course_with_content(course_data: dict, content_list: list):
    """
    Crée un cours avec son contenu (knowledges, flashcards, exercises) en utilisant des serializers
    
    Args:
        course_data (dict): Données du cours (name, user, academicLevel, etc.)
        content_list (list): Liste des éléments à créer avec leur type et données
            Format attendu pour chaque élément:
            {
                'type': 'text'|'flashcard'|'exercise',
                'data': {
                    // Pour type 'text':
                    'title': str,
                    'content': dict,  # Format Quill Delta
                    
                    // Pour type 'flashcard':
                    'title': str,
                    'question': dict,  # Format Quill Delta
                    'answer': dict,    # Format Quill Delta
                    
                    // Pour type 'exercise':
                    'title': str,
                    'instructions': dict,  # Format Quill Delta
                    'visibleAnswer': dict  # Format Quill Delta
                }
            }
    
    Returns:
        Course: L'instance (model) du cours créé
    """

    # Création du cours via serialize
    if not course_data['name']:
        print("[create_course_with_content] WARNING: Le nom du cours est vide")
        course_data['name'] = "Cours sans titre"
    course_serializer = CreateCourseSerializer(data=course_data)
    if not course_serializer.is_valid():
        print(f"[create_course_with_content] ERREUR: Données de cours invalides: {course_serializer.errors}")
        raise ValueError(f"Données de cours invalides: {course_serializer.errors}")
    course_model = course_serializer.save()
    course_content = []
    
    # Création des éléments associés via serializers
    for i, item in enumerate(content_list):
        data = item.get('data', {})
        data['course'] = course_model.publicIdentifier
        
        if item['type'] == 'text':
            knw_serializer = KnowledgeSerializer(data=data)
            if knw_serializer.is_valid():
                knw = knw_serializer.save()
                course_content.append(str(knw.publicIdentifier))
            else:
                print(f"[create_course_with_content] ERREUR: Données de knowledge invalides: {knw_serializer.errors}")
                raise ValueError(f"Données de knowledge invalides: {knw_serializer.errors}")
                
        elif item['type'] == 'flashcard':
            flc_serializer = FlashcardSerializer(data=data)
            if flc_serializer.is_valid():
                flc = flc_serializer.save()
                course_content.append("#F#" + str(flc.publicIdentifier))
            else:
                raise ValueError(f"Données de flashcard invalides: {flc_serializer.errors}")
                
        elif item['type'] == 'exercise':
            exr_serializer = ExerciseSerializer(data=data)
            if exr_serializer.is_valid():
                exr = exr_serializer.save()
                course_content.append("#E#" + str(exr.publicIdentifier))
            else:
                raise ValueError(f"Données d'exercise invalides: {exr_serializer.errors}")
    
    # Mise à jour du contenu du cours
    course_model.content = course_content
    course_model.save()
    
    return course_model