from django.contrib import messages
from django.core.cache import cache
from django.db import IntegrityError, transaction
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils import timezone

from .forms import ConsultationRequestForm
from .models import ConsultationSlot


# Антиспам: не более 3 заявок с одного IP за 10 минут
SUBMIT_LIMIT = 3
SUBMIT_WINDOW_SECONDS = 600


def _client_ip(request):
    # X-Forwarded-For добавляет nginx; берём первый адрес (реальный клиент)
    xff = request.META.get("HTTP_X_FORWARDED_FOR")
    if xff:
        return xff.split(",")[0].strip()
    return request.META.get("REMOTE_ADDR", "unknown")


def _submit_allowed(request):
    key = f"submit:{_client_ip(request)}"
    now = timezone.now().timestamp()
    stamps = cache.get(key, [])
    stamps = [s for s in stamps if now - s < SUBMIT_WINDOW_SECONDS]
    if len(stamps) >= SUBMIT_LIMIT:
        cache.set(key, stamps, SUBMIT_WINDOW_SECONDS)
        return False
    stamps.append(now)
    cache.set(key, stamps, SUBMIT_WINDOW_SECONDS)
    return True


def home(request):
    if request.method == "POST":
        if not _submit_allowed(request):
            messages.error(
                request,
                "Слишком много заявок за короткое время. Попробуйте через 10 минут.",
            )
            return redirect(f"{reverse('consultations:home')}#booking")
        form = ConsultationRequestForm(request.POST)
        if form.is_valid():
            try:
                with transaction.atomic():
                    form.save()
            except IntegrityError:
                form.add_error("slot", "Это время только что занял другой ученик. Выберите другой слот.")
            else:
                messages.success(
                    request,
                    "Заявка принята. Игорь Олегович свяжется с вами для подтверждения консультации.",
                )
                return redirect(f"{reverse('consultations:home')}#booking")
    else:
        form = ConsultationRequestForm()

    return render(
        request,
        "consultations/home.html",
        {
            "form": form,
            "available_slot_count": ConsultationSlot.objects.available().count(),
        },
    )


def privacy_policy(request):
    return render(request, "consultations/privacy.html")
