from django.contrib import messages
from django.contrib.auth import views as auth_views
from django.urls import reverse_lazy
from django.utils import timezone

from .security import clear_failures, is_blocked, record_failure


class SecureLoginView(auth_views.LoginView):
    template_name = "registration/login.html"

    def post(self, request, *args, **kwargs):
        username = request.POST.get("username", "")
        if is_blocked(request, username):
            self._lockout_blocked = True
            form = self.get_form()
            form.add_error(None, "Too many failed login attempts. Please wait and try again.")
            return self.form_invalid(form)
        return super().post(request, *args, **kwargs)

    def form_invalid(self, form):
        if getattr(self, "_lockout_blocked", False):
            messages.error(self.request, "Login temporarily locked after repeated failed attempts.")
            return super().form_invalid(form)
        username = self.request.POST.get("username", "")
        attempt = record_failure(self.request, username)
        if attempt and attempt.blocked_until:
            messages.error(self.request, "Login temporarily locked after repeated failed attempts.")
        return super().form_invalid(form)

    def form_valid(self, form):
        clear_failures(self.request, self.request.POST.get("username", ""))
        return super().form_valid(form)


class SecurePasswordChangeView(auth_views.PasswordChangeView):
    template_name = "registration/password_change_form.html"
    success_url = reverse_lazy("password_change_done")

    def form_valid(self, form):
        response = super().form_valid(form)
        user = self.request.user
        user.force_password_change = False
        user.last_password_change_at = timezone.now()
        user.save(update_fields=["force_password_change", "last_password_change_at", "updated_at"])
        return response
