from django.forms import (
    Form,
    ModelForm,
    ModelMultipleChoiceField,
    ModelChoiceField,
    ChoiceField,
    CharField,
)
from django.forms import inlineformset_factory
from generic.forms import ExamAuthorFormMixin, ExamFormMixin, ExamGroupsFormMixin, ExamMarkerFormMixin

from shorts.models import (
    Abnormality,
    AnswerMarks,
    Examination,
    Question,
    QuestionFinding,
    QuestionImage,
    Region,
    SampleAnswer,
    UserAnswer,
    Exam,
)

from django.contrib.admin.widgets import FilteredSelectMultiple
from django.forms.widgets import RadioSelect, TextInput, Textarea
from django.contrib.auth.models import User

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Div, Field, HTML
from crispy_forms.bootstrap import InlineRadios


from dal import autocomplete

from autocomplete import widgets as htmx_widgets, Autocomplete, AutocompleteWidget, ModelAutocomplete, register as autocomplete_register
from generic.widgets import ExamSearchWidget


class QuestionSampleAnswerForm(ModelForm):
    class Meta:
        model = Question
        fields = []


class MarkQuestionForm(Form):
    # correct = forms.CharField(required=False)
    # half_correct = forms.CharField(required=False)
    # incorrect = forms.CharField(required=False)
    marked_answers = CharField(required=False)


#class QuestionAnswerForm(ModelForm):
#    class Meta:
#        model = Question
#        fields = []

class QuestionForm(ModelForm):

    # exams = ModelMultipleChoiceField(required=False, queryset=Exam.objects.all(),widget=FilteredSelectMultiple(verbose_name="Exams", is_stacked=False))
    class Media:
        # Django also includes a few javascript files necessary
        # for the operation of this form element. You need to
        # include <script src="/admin/jsi18n"></script>
        # in the template.
        css = {
            "all": ["css/widgets.css"],
        }
        # Adding this javascript is crucial
        js = ["jsi18n.js", "tesseract.min.js", "js/upload_form_helpers.js"]

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop(
            "user"
        )  # To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
        if kwargs.get("instance"):
            # We get the 'initial' keyword argument or initialize it
            # as a dict if it didn't exist.
            initial = kwargs.setdefault("initial", {})
            # The widget for a ModelMultipleChoiceField expects
            # a list of primary key for the selected data.
            initial["exams"] = [t.pk for t in kwargs["instance"].exams.all()]

        ModelForm.__init__(self, *args, **kwargs)
        super(QuestionForm, self).__init__(*args, **kwargs)


        self.helper = FormHelper()
        self.helper.form_id = 'id-anatomy-question-form'
        self.helper.form_tag = False

        self.helper.layout = Layout(
            Div(
            HTML("<h4 class='clear-both' id='examination-label'>Examination*</h4>"),
            Field('examination', css_class='form-control'),
            Field('history', css_class='form-control'),
            Field('marking_guidance', css_class='form-control'),
            Field('feedback', css_class='form-control'),
            Field('open_access', css_class='form-control'),
            HTML("<h4 class='clear-both' id='exams-label'>Exams</h4>"),
            Field('exams', css_class='form-control'),
        ))

        self.fields["examination"] = ModelMultipleChoiceField(
            queryset=Examination.objects.all(),
            widget=FilteredSelectMultiple(verbose_name="Examination", is_stacked=False),
        )
        self.fields["examination"].label = ""

        if self.user.groups.filter(name="shorts_checker").exists():
            exam_queryset = Exam.objects.all()
        else:
            exam_queryset = Exam.objects.filter(
                author__id=self.user.id
            ) | Exam.objects.filter(open_access=True)

        self.fields["exams"] = ModelMultipleChoiceField(
            required=False,
            queryset=exam_queryset.distinct(),
            widget=ExamSearchWidget(exam_model=Exam),
        )
        self.fields["exams"].label = ""

        self.fields["history"].widget = Textarea(
            attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 1}
        )

    def save(self, commit=True):
        instance = ModelForm.save(self, False)
        instance.save()

        old_exams = instance.exams.all()

        new_exams = self.cleaned_data["exams"]

        for exam in old_exams:
            if exam not in new_exams:
                exam.exam_questions.remove(instance)

        for exam in new_exams:
            exam.exam_questions.add(instance)
            #exam.save()

        #        # Prepare a 'save_m2m' method for the form,
        #        old_save_m2m = self.save_m2m
        #
        #        def save_m2m():
        #            old_save_m2m()
        #            # This is where we actually link the pizza with toppings
        #            instance.exams.clear()
        #            for exam in self.cleaned_data["exams"]:
        #                instance.exams.add(exam)
        #
        #        self.save_m2m = save_m2m
        #
        #        # Do we need to save all changes now?
        #        # if commit:
        #        instance.save()
        self.save_m2m()

        return instance

    class Meta:
        model = Question
        # fields = ['due_back']
        # fields = '__all__'
        fields = [
            "examination",
            # "site",
            "feedback",
            "history",
            "marking_guidance",
            "open_access",
        ]
        # fields = ['question', 'feedback', 'subspecialty', 'references']

ImageFormSet = inlineformset_factory(
    Question,
    QuestionImage,
    fields=["image", "feedback_image", "filename", "description"],
    exclude=[],
    can_delete=True,
    extra=1,
    max_num=10,
)

#AnswerFormSet = inlineformset_factory(
#    Question,
#    SampleAnswer,
#    fields=["answer", "status"],
#    widgets={
#        "answer": Textarea(
#            attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
#        )
#    },
#    exclude=[],
#    can_delete=True,
#    extra=0,
#    max_num=10,
#)
#
SampleAnswerUpdateFormSet = inlineformset_factory(
    Question,
    SampleAnswer,
    fields=["answer", "score", "proposed"],
    widgets={
        "answer": Textarea(
            attrs={"required": "false", "minlength": 2, "maxlength": 500, "rows": 3}
        )
    },
    exclude=[],
    can_delete=True,
    extra=0,
    max_num=10,
)


# This should be made generic?
class ExamForm(ExamFormMixin, ModelForm):
    class Meta(ExamFormMixin.Meta):
        model = Exam

class ExamAuthorForm(ExamAuthorFormMixin):
    class Meta(ExamAuthorFormMixin.Meta):
        model = Exam

class ExamMarkerForm(ExamMarkerFormMixin):
    class Meta(ExamMarkerFormMixin.Meta):
        model = Exam

class ExamGroupsForm(ExamGroupsFormMixin):
    class Meta(ExamGroupsFormMixin.Meta):
        model = Exam

class QuestionFindingForm(ModelForm):
    class Meta:
        model = QuestionFinding
        exclude = ["question", "annotation_json", "viewport_json", "current_image_id_index"]

        widgets = {
            "findings": autocomplete.ModelSelect2Multiple(
                url="atlas:finding-autocomplete"
            ),
            "structures": autocomplete.ModelSelect2Multiple(
                url="atlas:structure-autocomplete"
            ),
            "conditions": autocomplete.ModelSelect2Multiple(
                url="atlas:condition-autocomplete"
            ),

        }

    def __init__(self, *args, **kwargs):
        if kwargs.get("question_id"):
            initial = kwargs.setdefault("initial", {})
            initial["question"] = kwargs.pop("question_id")

        super(QuestionFindingForm, self).__init__(*args, **kwargs)

        ModelForm.__init__(self, *args, **kwargs)

class MarkQuestionSingleForm(ModelForm):
    class Meta:
        model = UserAnswer
        fields = ["score", "candidate_feedback", "marker_feedback"]

        widgets = {
            "candidate_feedback": Textarea(attrs={"rows": 3}),
            "marker_feedback": Textarea(attrs={"rows": 3}),
        }

class MarkQuestionDoubleForm(ModelForm):
    class Meta:
        model = AnswerMarks
        fields = ["score", "mark_reason"]