from __future__ import annotations

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q


class UsernameOrEmailBackend(ModelBackend):
    """Authenticate users via either username or email."""

    def authenticate(self, request, username=None, password=None, **kwargs):
        login_value = kwargs.get("email") or username
        if not login_value or not password:
            return None

        UserModel = get_user_model()
        user = (
            UserModel.objects.filter(Q(username__iexact=login_value) | Q(email__iexact=login_value))
            .order_by("id")
            .first()
        )

        if user and user.check_password(password) and self.user_can_authenticate(user):
            return user
        return None
