from django.utils import timezone
import uuid
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.urls import reverse
from django.contrib import messages
from .models import QivipQuiz, QivipQuestion, QivipQuizFavorite, QuestionImage, QuizImage
from .forms import QuizForm, QuestionForm
import json
from django.core.paginator import Paginator
from .models import QivipQuiz
from .forms import QuizFilterForm
from django.db.models import Count
from django.contrib.auth.models import User
# Übersicht aller Quizze


def quiz_names_json(request):
    form = QuizFilterForm(request.GET)
    if form.is_valid():
        search = form.cleaned_data.get('search')
        names = list(
    QivipQuiz.objects.all().annotate(max_amout_questions=Count('questions')).filter(max_amout_questions__gte=1, status='öffentlich', name__icontains=search)
    .values_list('name', flat=True)
    .distinct()
)
    return JsonResponse(names, safe=False)

def overview_quiz(request):
    # Filter
    form = QuizFilterForm(request.GET)
    try:
        favorite_quizzes_data = QivipQuizFavorite.objects.filter(user=request.user, favorite=True).order_by("-favorite_date")
        favorite_quiz_ids = favorite_quizzes_data.values_list('quiz', flat=True)
        favorite_quizzes = QivipQuiz.objects.filter(id__in=favorite_quiz_ids)
    except:
        favorite_quizzes_data = QivipQuizFavorite.objects.none()
        favorite_quizzes = QivipQuizFavorite.objects.none()
        favorite_quiz_ids = favorite_quizzes.none()
        favorite_quizzes = QivipQuiz.objects.none()

    # Initialize querysets
    if request.user.is_authenticated:
        filter_my_quizzes = QivipQuiz.objects.filter(user_id=request.user).annotate(max_amout_questions=Count('questions'))
        favorite_quizzes = favorite_quizzes.filter(id__in=favorite_quiz_ids).annotate(max_amout_questions=Count('questions'))
        filter_other_quizzes = QivipQuiz.objects.exclude(user_id=request.user)
    else:
        favorite_quizzes = QivipQuiz.objects.none()
        filter_my_quizzes = QivipQuiz.objects.none()
        filter_other_quizzes = QivipQuiz.objects.all()
    
    # Apply common filters to other quizzes
    filter_other_quizzes = filter_other_quizzes.annotate(max_amout_questions=Count('questions'))
    filter_other_quizzes = filter_other_quizzes.filter(max_amout_questions__gte=1, status='öffentlich')


  


    if form.is_valid():
        
        search = form.cleaned_data.get('search')
        username= form.cleaned_data.get('user')
        max_amout_questions= form.cleaned_data.get('max_amout_questions')
        min_amout_questions= form.cleaned_data.get('min_amout_questions')
        
        filters = {}
        if username:
            try:
                user = User.objects.get(username=username)
                filters['user_id'] = user.id
            except User.DoesNotExist:
                favorite_quizzes = QivipQuiz.objects.none()
                filter_my_quizzes = QivipQuiz.objects.none()
                filter_other_quizzes=QivipQuiz.objects.none()

        if search:
            filters['name__icontains'] = search
        if  min_amout_questions:
            filters['max_amout_questions__gte'] =  min_amout_questions
        if max_amout_questions:
            filters['max_amout_questions__lte'] = max_amout_questions

        try:
           filter_other_quizzes = filter_other_quizzes.filter(**filters)
        except:
            filter_other_quizzes=QivipQuiz.objects.none()
        try:
           filter_my_quizzes = filter_my_quizzes.filter(**filters)
        except:
            filter_my_quizzes=QivipQuiz.objects.none()

        try:
            favorite_quizzes = favorite_quizzes.filter(**filters)
        except:
            favorite_quizzes=QivipQuiz.objects.none()

        

        # Pagination for my quizzes
        my_quizzes_paginator = Paginator(filter_my_quizzes.order_by('-creation_date'), 8)  # 8 quizzes per page
        try:
            my_quizzes = my_quizzes_paginator.page(request.GET.get('my_page', 1))
        except:
            my_quizzes = my_quizzes_paginator.page(1)

        # Pagination for other quizzes
        other_quizzes_paginator = Paginator(filter_other_quizzes.order_by('-creation_date'), 8)  # 8 quizzes per page
        try:
            other_quizzes = other_quizzes_paginator.page(request.GET.get('other_page', 1))
        except:
            other_quizzes = other_quizzes_paginator.page(1)

  

        try:
            favorite_quizzes = favorite_quizzes.filter(
            favorites__user=request.user,  # Filtere nach dem User
            favorites__favorite=True  # Filtere nach favorisierten Quizzes
            ).order_by('-favorites__favorite_date')
        except:
            pass


        # Pagination for favorite_quizzes
        favorite_quizzes_paginator = Paginator(favorite_quizzes, 8)  # 8 quizzes per page
        try:
           favorite_quizzes = favorite_quizzes_paginator.page(request.GET.get('my_page', 1))
        except:
            favorite_quizzes = favorite_quizzes_paginator.page(1)

        context = {
            'show_search': True,
            'favorite_quiz_ids': favorite_quiz_ids,
            'favorite_quizzes':favorite_quizzes,
            'my_quizzes': my_quizzes,
            'other_quizzes': other_quizzes,
            'form': form,
        }

        return render(request, 'library/overview_quiz.html', context)
      
# Neues Quiz erstellen
@login_required
def favorite_quiz(request, pk):
    quiz= get_object_or_404(QivipQuiz, pk=pk)
    favorite = QivipQuizFavorite.objects.filter(user=request.user, quiz=quiz).first()
    
    if favorite:
        favorite.favorite=not favorite.favorite
        


        if favorite.favorite==True:
            favorite.favorite_date = timezone.now()          
            favorite.save()
        else:
            favorite.favorite_date = None
            favorite.delete()
            statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich von den Favoriten entfernt!"
            messages.error(request, statement)
    
        
    else:
       favorite=QivipQuizFavorite.objects.create(user=request.user, quiz=quiz, favorite=True, favorite_date=timezone.now())
       statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich zu den Favoriten hinzugefügt!"
       messages.success(request,statement )
    return redirect(request.META.get('HTTP_REFERER', 'library:overview_quiz'))
    
    
# Neues Quiz erstellen
@login_required
def new_quiz(request):

        
    if request.method == 'POST':


        form = QuizForm(request.POST, request.FILES)
        if form.is_valid():
            quiz = form.save(commit=False)
            try:
                quiz_image=request.FILES['quiz_image']
                imagequiz=QuizImage.objects.create(image=quiz_image)
                quiz.image=imagequiz

            except:
                pass

            
            quiz.user_id = request.user
            #quiz.creator = request.user
            quiz.save()
            #form.save_m2m()  # Speichert die Many-to-Many Beziehungen (Tags)
            return redirect('library:detail_quiz', pk=quiz.pk)
            
    else:
        form = QuizForm()
    return render(request, 'library/form.html', {'form': form})

# Quiz bearbeiten
@login_required
def edit_quiz(request, pk):
    quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user)
    if request.method == 'POST':
        form = QuizForm(request.POST, instance=quiz, files=request.FILES) 
        if form.is_valid():

            if 'reset_image' in request.POST:
                quiz.image = None

            try:
                quiz_image=request.FILES['quiz_image']
                imagequiz=QuizImage.objects.create(image=quiz_image)
                quiz.image=imagequiz


            except:
                pass

            
            
            form.save()
            for img in QuizImage.objects.all():
                try:
                    img.delete()
                    img.image.delete(save=False)
                except:
                    pass
            return redirect('library:detail_quiz', pk=pk)
            #return modified(request, pk)
            
    else:
        form = QuizForm(instance=quiz)
    return render(request, 'library/form.html', {'form': form})
    
# Quiz löschen
@login_required
def delete_quiz(request, pk):
    quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user)
    if request.method == 'POST':
        quiz.delete()
        for img in QuizImage.objects.all():
            try:
                img.delete()
                img.image.delete(save=False)
            except:
                pass
        for img in QuestionImage.objects.all():
            try:
                img.delete()
                img.image.delete(save=False)
            except:
                pass

        return redirect('library:overview_quiz')
    return render(request, 'library/delete_confirmation.html', {'object': quiz})

# Quiz anzeigen
def detail_quiz(request, pk):
    #quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user)
    quiz = get_object_or_404(QivipQuiz, pk=pk)
    show_answers = request.GET.get('show_answers', 'false').lower() == 'true'
    questions = QivipQuestion.objects.filter(quiz_id=quiz)
    # Parse JSON data for each question
    for question in questions:
        if question.data:
            question.data = json.loads(question.data)

    context = {
        'quiz': quiz,
        'questions': questions,
        'detail':show_answers,
    }
    return render(request, 'library/detail_quiz.html', context)


@login_required
def copy_quiz(request, pk):
    original_quiz = get_object_or_404(QivipQuiz, pk=pk)

    
    
    # Quiz kopieren (ohne ID, damit ein neues Objekt erstellt wird)
 
        # Quiz kopieren (ohne ID, damit ein neues Objekt erstellt wird)

    new_quiz = original_quiz     # Kopie erstellen (aber Achtung: Noch gleiche Referenz!)
    new_quiz.pk = None  # Setzt die ID auf None, damit Django es als neues Objekt erkennt
    new_quiz.uuid = uuid.uuid4()  # Neue UUID generieren
    new_quiz.user_id = request.user  # Neuer Besitzer ist der aktuelle User
    new_quiz.name += " - Kopie"
    new_quiz.base_quiz_id = pk
    new_quiz.rating_count = 0
    new_quiz.average_rating = 3.0
    new_quiz.save()  # Speichern als neues Objekt 
   # Optional: Beschreibung anpassen
    # Alle zugehörigen Fragen kopieren
    questions = QivipQuestion.objects.filter(quiz_id=pk)
    for question in questions:
        question.uuid = uuid.uuid4()
        question.pk = None  # Setze pk auf None, damit es als neues Objekt gespeichert wird
        question.quiz_id = original_quiz  # Verknüpfe mit dem neuen Quiz
        question.data = question.data  # `data`-Feld wird explizit übernommen # Verknüpfe mit dem neuen Quiz

        question.save()
    
    messages.success(request, "Quiz wurde erfolgreich kopiert!")
    return redirect('library:detail_quiz', pk=new_quiz.pk)


# Übersicht aller Fragen
@login_required
def question_list(request):
    questions = QivipQuestion.objects.filter(quiz_id__user_id=request.user)
    
    # Parse JSON data for each question
    for question in questions:
        if question.data:
            question.data = json.loads(question.data)
    
    return render(request, 'library/question_list.html', {'questions': questions})

# Neue Frage erstellen
@login_required 
def new_question(request):
    question_type = request.GET.get('type')
    quiz_id = request.GET.get('quiz_id')
    
    if not quiz_id:
        messages.error(request, 'Quiz ID muss angegeben werden.')
        return redirect('library:overview_quiz')
        
    try:
        quiz = QivipQuiz.objects.get(pk=quiz_id, user_id=request.user)
    except QivipQuiz.DoesNotExist:
        messages.error(request, 'Quiz nicht gefunden oder keine Berechtigung.')
        return redirect('library:overview_quiz')
    
    if question_type not in ['multiple_choice', 'true_false','input']:
        base_url = reverse('library:new_question')
        return redirect(f'{base_url}?type=multiple_choice&quiz_id={quiz_id}')
       
    if request.method == 'POST':
        question_text = request.POST.get('question', '')
        
        # Handle different question types
        if question_type == 'true_false':
            correct_answer = request.POST.get('correct_answer') == 'true'
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': [
                    {'value': 'Wahr', 'is_correct': correct_answer},
                    {'value': 'Falsch', 'is_correct': not correct_answer}
                ]
            }

        elif question_type == 'input':
            correct_answer = request.POST.get('correct_answer')
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': [
                    {'value': correct_answer, 'is_correct': True}
                    
                ]
            } 
        elif question_type == 'multiple_choice':
            options = []
            i = 1
            # Limit to maximum 6 options
            while request.POST.get(f'option_{i}') and i <= 6:
                is_correct = request.POST.get(f'correct_{i}') == '1'
                options.append({
                    'order': i,
                    'value': request.POST.get(f'option_{i}'),
                    'is_correct': is_correct
                })
                i += 1
                
            # Validate minimum 2 options
            if len(options) < 2:
                messages.error(request, 'Mindestens zwei Optionen müssen angegeben werden.')
                return redirect(request.get_full_path())
                
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': options
            }
        
        question = QivipQuestion()
        question.data = json.dumps(json_data)
        question.quiz_id = quiz
        try:
            question_image=request.FILES['question_image']
            imagequestion=QuestionImage.objects.create(image=question_image)
            question.image=imagequestion
        except:
            pass


        question.time_per_question = request.POST.get('time_per_question', '30')
        question.save()
        #return modified(request, pk=quiz.pk)
        return redirect('library:detail_quiz', pk=quiz.pk)
    else:
        # Initialize empty question data for new questions
        if question_type == 'true_false':
            question_data = {
                'type': question_type,
                'question': '',
                'options': [
                    {'value': 'Wahr', 'is_correct': True},
                    {'value': 'Falsch', 'is_correct': False}
                ]
            }
            standard_time_per_question = 30

        elif question_type == 'input':
            question_data = {
                'type': question_type,
                'question': '',
                'options': [
                    
                    
                ]
            } 
            standard_time_per_question = 30

        elif question_type == 'multiple_choice':
            question_data = {
                'type': question_type,
                'question': '',
                'options': [
                    {'value': '', 'is_correct': False},
                    {'value': '', 'is_correct': False}
                ]
            }
            standard_time_per_question = 30
    
    template_name = f'library/question/question_{question_type}.html'
    context = {
        'question': question_data,
        'quiz_id': quiz_id,
        'quiz': quiz,
        'standard_time_per_question': standard_time_per_question,
    }
    
    return render(request, template_name, context)

# Frage bearbeiten
@login_required
def edit_question(request, pk):
    question = get_object_or_404(QivipQuestion, pk=pk, quiz_id__user_id=request.user)
    if 'reset_ques_image' in request.POST:
                question.image = None
    if question.quiz_id.user_id != request.user:
        return redirect('library:question_list')
    
    # Parse the existing JSON data
    try:
        question_data = json.loads(question.data) if question.data else {}
        question_type = question_data.get('type', 'multiple_choice')
        question_image = question.image
        
        # For true/false questions, get the correct answer from the options
        if question_type == 'true_false':
            # Default to true if no options exist
            correct_answer = True
            if question_data.get('options'):
                correct_answer = question_data['options'][0].get('is_correct', True)
            question_data = {
                'type': question_type,
                'question': question_data.get('question', ''),
                'correct_answer': correct_answer,  # Add this for template compatibility
                'options': [
                    {'value': 'Wahr', 'is_correct': correct_answer},
                    {'value': 'Falsch', 'is_correct': not correct_answer}
                ]
            }
        else:
            # For multiple choice questions
            question_data.setdefault('type', question_type)
            question_data.setdefault('question', '')
            question_data.setdefault('options', [])
            
    except (json.JSONDecodeError, AttributeError):
        # Handle invalid JSON or None data
        question_type = question_data.get('type', 'multiple_choice')
        if question_type == 'true_false':
            question_data = {
                'type': question_type,
                'question': '',
                'correct_answer': True,  # Default to true for new questions
                'options': [
                    {'value': 'Wahr', 'is_correct': True},
                    {'value': 'Falsch', 'is_correct': False}
                ]
            }
        else:
            question_data = {
                'type': question_type,
                'question': '',
                'options': []
            }
        
    if request.method == 'POST':
        question_text = request.POST.get('question', '')
        try:
            question_image=request.FILES['question_image']
            imagequestion=QuestionImage.objects.create(image=question_image)
            question.image=imagequestion
        except Exception:
            pass

        # Handle different question types
        if question_type == 'true_false':
            correct_answer = request.POST.get('correct_answer') == 'true'
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': [
                    {'value': 'Wahr', 'is_correct': correct_answer},
                    {'value': 'Falsch', 'is_correct': not correct_answer}
                ]
            }
        elif question_type == 'input':
            correct_answer = request.POST.get('correct_answer')
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': [
                    {'value': correct_answer,'is_correct':True}
                    
                ]
            } 

        elif question_type == 'multiple_choice':
            options = []
            i = 1
            # Limit to maximum 6 options
            while request.POST.get(f'option_{i}') and i <= 6:
                options.append({
                    'order': i,
                    'value': request.POST.get(f'option_{i}'),
                    'is_correct': request.POST.get(f'correct_{i}') == '1'
                })
                i += 1
                
            # Validate minimum 2 options
            if len(options) < 2:
                messages.error(request, 'Mindestens zwei Optionen müssen angegeben werden.')
                return redirect(request.get_full_path())

            # Validate maximum 6 options
            if len(options) > 6:
                messages.error(request, 'Maximal 6 Optionen sind erlaubt.')
                return redirect(request.get_full_path())
                
            json_data = {
                'type': question_type,
                'question': question_text,
                'options': options
            }
            
        question.data = json.dumps(json_data)
        question.time_per_question = request.POST.get('time_per_question', '30')

        
        question.save()
        for img in QuestionImage.objects.all():
            try:
                img.delete()
                img.image.delete(save=False)
            except:
                pass
        #return modified(request, question.quiz_id.pk)
        return redirect('library:detail_quiz', pk=question.quiz_id.pk)
        
    else:
        template_name = f'library/question/question_{question_type}.html'
        context = {
            'question': {'data': question_data},  # Wrap in data structure expected by template
            'quiz_id': question.quiz_id.pk,
            'quiz': question.quiz_id,
            'time_per_question': question.time_per_question,
            'image': question_image,
        }
        
        return render(request, template_name, context)


# Frage löschen
@login_required
def delete_question(request, pk):
    question = get_object_or_404(QivipQuestion, pk=pk, quiz_id__user_id=request.user)
    
    # Parse JSON data for question
    if question.data:
        question.data = json.loads(question.data)
    
    if request.method == 'POST':
        question.delete()
        for img in QuestionImage.objects.all():
            try:
                img.delete()
                img.image.delete(save=False)
            except:
                pass
        return redirect('library:detail_quiz', pk=question.quiz_id.pk)
    return render(request, 'library/delete_confirmation.html', {'object': question})
