"""
Forms for certifications.
"""
from django import forms

from apps.certifications.models import (
    CertificationApplication,
    CertificationProgram,
    ExamChoice,
    ExamQuestion,
    TestScheduleSlot,
    TestingCenter,
)
from apps.courses.models import CATEGORY_BOTH, CATEGORY_CERT, Category


class CertificationProgramForm(forms.ModelForm):
    class Meta:
        model = CertificationProgram
        fields = [
            'title', 'category', 'short_description', 'full_description', 'thumbnail',
            'fee', 'reattempt_fee', 'related_course', 'teachers', 'questions_per_exam',
            'min_question_bank', 'passing_score', 'time_limit_minutes', 'results_delay_minutes',
            'max_attempts',
            'require_proctor', 'allow_center_exam', 'allow_remote_exam',
            'meeting_instructions', 'is_published',
        ]
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'category': forms.Select(attrs={'class': 'form-select'}),
            'short_description': forms.TextInput(attrs={'class': 'form-control'}),
            'full_description': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
            'thumbnail': forms.ClearableFileInput(attrs={'class': 'form-control'}),
            'fee': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}),
            'reattempt_fee': forms.NumberInput(attrs={
                'class': 'form-control', 'step': '0.01', 'min': '0',
                'placeholder': 'Leave blank = half of certification fee',
            }),
            'related_course': forms.Select(attrs={'class': 'form-select'}),
            'teachers': forms.CheckboxSelectMultiple(),
            'questions_per_exam': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
            'min_question_bank': forms.NumberInput(attrs={'class': 'form-control', 'min': '100'}),
            'passing_score': forms.NumberInput(attrs={'class': 'form-control', 'min': '1', 'max': '100'}),
            'time_limit_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '60'}),
            'results_delay_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '0', 'max': '60'}),
            'max_attempts': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
            'require_proctor': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'allow_center_exam': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'allow_remote_exam': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'meeting_instructions': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'is_published': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }
        help_texts = {
            'fee': 'Initial certification fee paid by the candidate.',
            'reattempt_fee': 'Optional. If empty, reattempt fee = half of certification fee.',
            'questions_per_exam': 'Random MCQs drawn per attempt for each student (default 100).',
            'min_question_bank': 'Minimum active MCQs that must exist before exams run (default 800).',
            'passing_score': 'Candidates need at least this % to pass (default 70).',
            'time_limit_minutes': (
                'Timer for the exam. Recommended 120 minutes for 100 MCQs (~72 sec each). '
                'Minimum = 1 minute × number of MCQs (100 minutes for 100 questions).'
            ),
            'results_delay_minutes': (
                'How long after submit before the score is shown (default 5). '
                '0 = show immediately. Cancelled exams always show immediately.'
            ),
            'max_attempts': 'Total attempts: typically 3 (1 first try + 2 reattempts after fail).',
            'require_proctor': 'Must unlock with a live teacher code (at center or remote meeting).',
            'allow_center_exam': 'Allow booking an in-person slot at a TSN Digital testing center.',
            'allow_remote_exam': 'Allow taking the exam online with a live remote proctor.',
            'meeting_instructions': 'Shown for remote exams (meeting link, schedule, what to bring).',
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        from apps.accounts.models import CustomUser
        self.fields['category'].queryset = Category.objects.filter(
            is_active=True,
            applies_to__in=[CATEGORY_CERT, CATEGORY_BOTH],
        )
        self.fields['category'].required = False
        self.fields['teachers'].queryset = CustomUser.objects.filter(role='teacher', is_active=True).order_by('full_name', 'username')
        self.fields['teachers'].required = False
        self.fields['teachers'].help_text = 'Assign teachers who will teach/proctor this certification.'

    def clean(self):
        cleaned = super().clean()
        q = cleaned.get('questions_per_exam') or 100
        t = cleaned.get('time_limit_minutes')
        min_t = max(60, int(q))
        recommended = max(min_t, int(round(q * 1.2)))
        if t is None or t < min_t:
            self.add_error(
                'time_limit_minutes',
                f'Minimum time is {min_t} minutes (1 minute per MCQ). '
                f'Recommended: {recommended} minutes.',
            )
        return cleaned


class ExamQuestionForm(forms.ModelForm):
    choice_a = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'class': 'form-control'}))
    choice_b = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'class': 'form-control'}))
    choice_c = forms.CharField(max_length=500, required=False, widget=forms.TextInput(attrs={'class': 'form-control'}))
    choice_d = forms.CharField(max_length=500, required=False, widget=forms.TextInput(attrs={'class': 'form-control'}))
    correct = forms.ChoiceField(
        choices=[('a', 'A'), ('b', 'B'), ('c', 'C'), ('d', 'D')],
        widget=forms.Select(attrs={'class': 'form-select'}),
        label='Correct answer',
    )

    class Meta:
        model = ExamQuestion
        fields = ['text', 'order', 'is_active']
        widgets = {
            'text': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'order': forms.NumberInput(attrs={'class': 'form-control'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def save_with_choices(self, program):
        question = self.save(commit=False)
        question.program = program
        question.save()
        question.choices.all().delete()
        mapping = {
            'a': self.cleaned_data['choice_a'],
            'b': self.cleaned_data['choice_b'],
            'c': self.cleaned_data.get('choice_c') or '',
            'd': self.cleaned_data.get('choice_d') or '',
        }
        correct = self.cleaned_data['correct']
        for key, text in mapping.items():
            if not text.strip():
                continue
            ExamChoice.objects.create(
                question=question,
                text=text.strip(),
                is_correct=(key == correct),
            )
        return question


class MCQBulkUploadForm(forms.Form):
    csv_file = forms.FileField(
        label='MCQ CSV file',
        help_text='Upload a .csv file using the sample format (question, choices, correct answer).',
        widget=forms.ClearableFileInput(attrs={
            'class': 'form-control',
            'accept': '.csv,text/csv',
        }),
    )

    def clean_csv_file(self):
        f = self.cleaned_data['csv_file']
        name = (f.name or '').lower()
        if not name.endswith('.csv'):
            raise forms.ValidationError('Please upload a .csv file.')
        if f.size and f.size > 8 * 1024 * 1024:
            raise forms.ValidationError('CSV file is too large (max 8 MB).')
        return f


class CertPaymentProofForm(forms.ModelForm):
    class Meta:
        model = CertificationApplication
        fields = ['payment_proof', 'payment_note']
        widgets = {
            'payment_proof': forms.ClearableFileInput(attrs={'class': 'form-control'}),
            'payment_note': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['payment_proof'].required = True


class CertificateVerifyForm(forms.Form):
    code = forms.CharField(
        min_length=14,
        max_length=14,
        label='Verification code',
        widget=forms.TextInput(attrs={
            'class': 'form-control form-control-lg text-uppercase font-monospace',
            'placeholder': 'CERT-XXXX-XXXX',
            'autocomplete': 'off',
            'maxlength': '14',
            'minlength': '14',
            'size': '14',
            'pattern': r'CERT-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}',
            'title': 'Format: CERT-XXXX-XXXX (exactly 14 characters)',
            'spellcheck': 'false',
            'inputmode': 'text',
        }),
    )

    def clean_code(self):
        import re
        code = (self.cleaned_data.get('code') or '').strip().upper()
        if not re.fullmatch(r'CERT-[A-Z0-9]{4}-[A-Z0-9]{4}', code):
            raise forms.ValidationError(
                'Enter a valid code in the format CERT-XXXX-XXXX.'
            )
        return code


class ProctorUnlockForm(forms.Form):
    code = forms.CharField(
        max_length=16,
        label='Exam unlock code',
        widget=forms.TextInput(attrs={
            'class': 'form-control form-control-lg text-uppercase font-monospace',
            'placeholder': 'EXAM-XXXX',
            'autocomplete': 'off',
        }),
    )


class CreateProctorSessionForm(forms.Form):
    meeting_url = forms.URLField(
        required=False,
        label='Meeting link (optional)',
        widget=forms.URLInput(attrs={
            'class': 'form-control',
            'placeholder': 'https://meet.google.com/... or Zoom link',
        }),
    )
    notes = forms.CharField(
        required=False,
        max_length=255,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional note'}),
    )
    hours_valid = forms.IntegerField(
        min_value=1,
        max_value=24,
        initial=2,
        label='Code valid for (hours)',
        widget=forms.NumberInput(attrs={'class': 'form-control'}),
    )


class TestingCenterForm(forms.ModelForm):
    class Meta:
        model = TestingCenter
        fields = [
            'name', 'address', 'city', 'phone', 'email',
            'map_url', 'directions', 'is_active', 'sort_order',
        ]
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'address': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'city': forms.TextInput(attrs={'class': 'form-control'}),
            'phone': forms.TextInput(attrs={'class': 'form-control'}),
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'map_url': forms.URLInput(attrs={'class': 'form-control'}),
            'directions': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'sort_order': forms.NumberInput(attrs={'class': 'form-control'}),
        }


class TestScheduleSlotForm(forms.ModelForm):
    class Meta:
        model = TestScheduleSlot
        fields = [
            'center', 'program', 'date', 'start_time', 'end_time',
            'capacity', 'is_active', 'notes',
        ]
        widgets = {
            'center': forms.Select(attrs={'class': 'form-select'}),
            'program': forms.Select(attrs={'class': 'form-select'}),
            'date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'start_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
            'end_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
            'capacity': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'notes': forms.TextInput(attrs={'class': 'form-control'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['program'].required = False
        self.fields['program'].empty_label = 'Any certification program'
