import logging

from django.contrib.auth import authenticate, login, logout
from django.core.cache import cache
from django.shortcuts import redirect, render
from django.utils.http import url_has_allowed_host_and_scheme
from django.views.decorators.http import require_POST

logger = logging.getLogger('it_management')

MAX_ATTEMPTS = 5          # تعداد تلاش ناموفق مجاز
LOCK_SECONDS = 10 * 60    # مدت قفل (ثانیه)


def _client_ip(request):
    # پشت reverse-proxy باید X-Forwarded-For را در همان پروکسی مدیریت کرد؛
    # در اینجا فقط REMOTE_ADDR مورد اعتماد است.
    return request.META.get('REMOTE_ADDR', 'unknown')


def _throttle_keys(request, username):
    ip = _client_ip(request)
    return (
        f'login_fail:ip:{ip}',
        f'login_fail:user:{(username or "").lower()[:150]}',
    )


def _is_locked(keys):
    return any((cache.get(k) or 0) >= MAX_ATTEMPTS for k in keys)


def _register_failure(keys):
    for k in keys:
        try:
            cache.incr(k)
        except ValueError:
            cache.set(k, 1, LOCK_SECONDS)


def _clear_failures(keys):
    for k in keys:
        cache.delete(k)


def login_view(request):
    if request.user.is_authenticated:
        return redirect('dashboard_home')

    next_url = request.POST.get('next') or request.GET.get('next') or ''

    if request.method == 'POST':
        username = (request.POST.get('username') or '').strip()
        password = request.POST.get('password') or ''
        keys = _throttle_keys(request, username)

        if _is_locked(keys):
            logger.warning('Login locked for user=%r ip=%s', username, _client_ip(request))
            return render(request, 'accounts/login.html', {
                'error': 'تلاش‌های ناموفق زیاد بود. لطفاً ۱۰ دقیقه بعد دوباره تلاش کنید.',
                'next': next_url,
            }, status=429)

        user = authenticate(request, username=username, password=password)

        if user is not None:
            _clear_failures(keys)
            login(request, user)

            if next_url and url_has_allowed_host_and_scheme(
                next_url,
                allowed_hosts={request.get_host()},
                require_https=request.is_secure(),
            ):
                return redirect(next_url)
            return redirect('dashboard_home')

        _register_failure(keys)
        logger.warning('Failed login user=%r ip=%s', username, _client_ip(request))

        return render(request, 'accounts/login.html', {
            'error': 'نام کاربری یا رمز عبور نادرست است.',
            'next': next_url,
        })

    return render(request, 'accounts/login.html', {'next': next_url})


@require_POST
def logout_view(request):
    logout(request)
    return redirect('login')
