# Standard Library
import sys
from types import SimpleNamespace
from unittest.mock import Mock, patch
from uuid import uuid4

# Django
from django.test import RequestFactory, SimpleTestCase

# Project
from django_easy_quiz.views.misc import DisplayPdfView


class _FakeFilterResult:
    def __init__(self, saved_quiz):
        self._saved_quiz = saved_quiz

    def first(self):
        return self._saved_quiz


class _FakeHTML:
    last_call = None

    def __init__(self, string, base_url):
        _FakeHTML.last_call = {"string": string, "base_url": base_url}

    def write_pdf(self):
        return b"%PDF-1.4 fake"


class DisplayPdfViewTests(SimpleTestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.identifier = uuid4()

    def test_pdf_view_weighted_quiz_includes_explanatory_flag(self):
        request = self.factory.get("/pdf/test?name=quiz_result")
        saved_quiz = SimpleNamespace(
            interpretation_quiz=None,
            weighted_answers_quiz=SimpleNamespace(show_answers_corrections_text=True),
            answers=[
                {
                    "question": {"label": "Q1"},
                    "answers": ["A1"],
                    "question_explanation_text": "<p>Info Q1</p>",
                }
            ],
            conclusion={"points": 4, "description": "<p>Done</p>"},
        )
        render_mock = Mock(return_value="<html>ok</html>")

        with patch(
            "django_easy_quiz.views.misc.SavedQuiz.objects.filter",
            return_value=_FakeFilterResult(saved_quiz),
        ), patch(
            "django_easy_quiz.views.misc.render_to_string",
            render_mock,
        ), patch.dict(
            sys.modules, {"weasyprint": SimpleNamespace(HTML=_FakeHTML)}
        ):
            response = DisplayPdfView().get(request, identifier=self.identifier)

        self.assertEqual(response["Content-Type"], "application/pdf")
        self.assertEqual(response["Content-Disposition"], "filename=quiz_result.pdf")
        context = render_mock.call_args[0][1]
        self.assertEqual(context["quiz_type"], "weighed_answers_quiz")
        self.assertTrue(context["final_quiz_show_answers_corrections_text"])

    def test_pdf_view_interpretation_quiz_disables_explanatory_flag_and_default_name(
        self,
    ):
        request = self.factory.get("/pdf/test")
        saved_quiz = SimpleNamespace(
            interpretation_quiz=SimpleNamespace(id=1),
            weighted_answers_quiz=None,
            answers=[{"question": {"label": "Q1"}, "answer": "■ - A"}],
            conclusion="Interpretation text",
        )
        render_mock = Mock(return_value="<html>ok</html>")

        with patch(
            "django_easy_quiz.views.misc.SavedQuiz.objects.filter",
            return_value=_FakeFilterResult(saved_quiz),
        ), patch(
            "django_easy_quiz.views.misc.render_to_string",
            render_mock,
        ), patch.dict(
            sys.modules, {"weasyprint": SimpleNamespace(HTML=_FakeHTML)}
        ):
            response = DisplayPdfView().get(request, identifier=self.identifier)

        self.assertEqual(response["Content-Disposition"], "filename=document.pdf")
        context = render_mock.call_args[0][1]
        self.assertEqual(context["quiz_type"], "interpretation_quiz")
        self.assertFalse(context["final_quiz_show_answers_corrections_text"])
