from django.shortcuts import render, redirect
from django.contrib import messages
from accounts.mixins import StudentRequiredMixin, TeacherRequiredMixin
from django.views import View
from admissions.documents import DocumentUploadForm, save_application_document, document_checklist
from admissions.models import ApplicationDocument
from .forms import StudentProfileUpdateForm, TeacherProfileUpdateForm, StudentContactForm
from .models import StudentProfile, TeacherProfile


class StudentProfileView(StudentRequiredMixin, View):
    template_name = 'student/profile.html'

    def _linked_application(self, request):
        enrollment = getattr(request.user, 'enrollment', None)
        application = getattr(request.user, 'application', None)
        if application is None and enrollment is not None:
            application = enrollment.application
        unlocked = bool(enrollment and enrollment.edits_unlocked)
        return enrollment, application, unlocked

    def _context(self, request, profile, **overrides):
        enrollment, application, unlocked = self._linked_application(request)
        ctx = {
            'form': StudentProfileUpdateForm(user=request.user, instance=profile),
            'application': application,
            'edits_unlocked': unlocked,
            'contact_form': StudentContactForm(instance=application) if application else None,
            'documents': document_checklist(application) if application else None,
            'doc_upload_form': DocumentUploadForm(),
        }
        ctx.update(overrides)
        return ctx

    def get(self, request):
        profile, _ = StudentProfile.objects.get_or_create(user=request.user)
        return render(request, self.template_name, self._context(request, profile))

    def post(self, request):
        profile, _ = StudentProfile.objects.get_or_create(user=request.user)
        enrollment, application, unlocked = self._linked_application(request)
        form_type = request.POST.get('form_type', 'profile')

        # Photo/bio/name can always be edited (cosmetic personal details).
        if form_type == 'profile':
            form = StudentProfileUpdateForm(
                user=request.user, data=request.POST, files=request.FILES, instance=profile
            )
            if form.is_valid():
                form.save()
                messages.success(request, 'Profile updated successfully.')
                return redirect('profiles:student_profile')
            return render(request, self.template_name, self._context(request, profile, form=form))

        # Contact details and documents are locked until an admin enables editing.
        if not unlocked or not application:
            messages.error(request, 'Editing is locked. Please ask the administrator to enable it.')
            return redirect('profiles:student_profile')

        if form_type == 'contact':
            contact_form = StudentContactForm(data=request.POST, instance=application)
            if contact_form.is_valid():
                contact_form.save()
                messages.success(request, 'Contact details updated successfully.')
                return redirect('profiles:student_profile')
            return render(request, self.template_name, self._context(request, profile, contact_form=contact_form))

        if form_type == 'document':
            doc_form = DocumentUploadForm(request.POST, request.FILES)
            if doc_form.is_valid():
                _, created = save_application_document(
                    application, doc_form.cleaned_data['document_type'], doc_form.cleaned_data['file']
                )
                label = dict(ApplicationDocument.DOCUMENT_TYPE_CHOICES)[doc_form.cleaned_data['document_type']]
                messages.success(request, f'{label} {"uploaded" if created else "replaced"} successfully.')
            else:
                first_error = next(iter(doc_form.errors.values()))[0] if doc_form.errors else 'Could not upload the file.'
                messages.error(request, first_error)
            return redirect('profiles:student_profile')

        return redirect('profiles:student_profile')


class TeacherProfileView(TeacherRequiredMixin, View):
    template_name = 'teacher/profile.html'

    def get(self, request):
        profile, _ = TeacherProfile.objects.get_or_create(user=request.user)
        form = TeacherProfileUpdateForm(user=request.user, instance=profile)
        assigned_programs = profile.programs.all()
        return render(request, self.template_name, {'form': form, 'assigned_programs': assigned_programs})

    def post(self, request):
        profile, _ = TeacherProfile.objects.get_or_create(user=request.user)
        form = TeacherProfileUpdateForm(user=request.user, data=request.POST, files=request.FILES, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, 'Profile updated successfully.')
            return redirect('profiles:teacher_profile')
        assigned_programs = profile.programs.all()
        return render(request, self.template_name, {'form': form, 'assigned_programs': assigned_programs})
