# Standard Library
from types import SimpleNamespace

# Django
from django.contrib.admin.sites import AdminSite
from django.contrib.messages.storage.fallback import FallbackStorage
from django.test import RequestFactory, TestCase

# Project
from django_easy_quiz.admin import WeightedAnswersQuizAdmin, nb_of_questions
from django_easy_quiz.forms import InterpretationQuizForm, WeightedAnswersQuizForm
from django_easy_quiz.models import (
    InterpretationQuiz,
    InterpretationQuizAnswer,
    InterpretationQuizConclusion,
    InterpretationQuizQuestion,
    MoreInfoAnswer,
    MoreInfoQuestion,
    MoreInfoQuiz,
    WeightedAnswersQuiz,
    WeightedAnswersQuizAnswer,
    WeightedAnswersQuizQuestion,
)
from django_easy_quiz.utils import get_more_info_quiz_formset, get_quiz_and_formset


class UtilsTests(TestCase):
    def test_get_quiz_and_formset_weighted_filters_empty_answers(self):
        quiz = WeightedAnswersQuiz.objects.create(name="W", description="D")
        question = WeightedAnswersQuizQuestion.objects.create(quiz=quiz, label="Q")
        WeightedAnswersQuizAnswer.objects.create(
            question=question, label="A1", points=1, order=1
        )
        _, formset = get_quiz_and_formset(
            WeightedAnswersQuiz, WeightedAnswersQuizForm, quiz.id
        )
        answers = formset.forms[0].initial["answers"]
        self.assertEqual(len(answers), 1)
        self.assertEqual(answers[0]["label"], "A1")

    def test_get_quiz_and_formset_interpretation_symbols(self):
        quiz = InterpretationQuiz.objects.create(name="I", description="D")
        for sym, desc in zip(
            ("■", "▲", "◆", "●"),
            ("c1", "c2", "c3", "c4"),
        ):
            InterpretationQuizConclusion.objects.create(
                quiz=quiz, symbol=sym, description=desc
            )
        iq = InterpretationQuizQuestion.objects.create(quiz=quiz, label="QI")
        InterpretationQuizAnswer.objects.create(
            question=iq, symbol="■", label="A1", order=1
        )
        InterpretationQuizAnswer.objects.create(
            question=iq, symbol="▲", label="A2", order=2
        )
        InterpretationQuizAnswer.objects.create(
            question=iq, symbol="●", label="A4", order=4
        )
        _, formset = get_quiz_and_formset(
            InterpretationQuiz, InterpretationQuizForm, quiz.id
        )
        answers = formset.forms[0].initial["answers"]
        self.assertEqual([a["symbol"] for a in answers], ["■", "▲", "●"])

    def test_get_more_info_quiz_formset_builds_answers(self):
        more_info_quiz = MoreInfoQuiz.objects.create(name="Stats")
        question = MoreInfoQuestion.objects.create(label="Age", quiz=more_info_quiz)
        answer = MoreInfoAnswer.objects.create(question=question, answer="18-25")
        formset = get_more_info_quiz_formset(more_info_quiz)
        self.assertEqual(formset.forms[0].initial["answers"][0]["id"], answer.id)


class AdminTests(TestCase):
    def test_nb_of_questions_works_for_both_quiz_types(self):
        weighted_obj = SimpleNamespace(
            weightedanswersquizquestion_set=SimpleNamespace(all=lambda: [1, 2, 3])
        )
        interpretation_obj = SimpleNamespace(
            interpretationquizquestion_set=SimpleNamespace(all=lambda: [1, 2])
        )
        self.assertEqual(nb_of_questions(weighted_obj), "3")
        self.assertEqual(nb_of_questions(interpretation_obj), "2")

    def test_weighted_admin_response_change_without_errors(self):
        quiz = WeightedAnswersQuiz.objects.create(name="W2", description="D2")
        request = RequestFactory().post("/")
        request.user = SimpleNamespace(
            is_active=True,
            is_staff=True,
            is_superuser=True,
            has_perm=lambda perm: True,
        )
        request.session = {}
        request._messages = FallbackStorage(request)
        admin_obj = WeightedAnswersQuizAdmin(WeightedAnswersQuiz, AdminSite())
        response = admin_obj.response_change(request, quiz)
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.url, "/admin/django_easy_quiz/weightedanswersquiz/")
