import json
import logging
from urllib.parse import urlencode
from urllib.request import Request, urlopen

from django.conf import settings
from django.core.mail import EmailMessage
from django.db import models
from django.http import HttpResponsePermanentRedirect
from django.shortcuts import render
from wagtail.admin.panels import FieldPanel, MultiFieldPanel
from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
from wagtail.fields import RichTextField
from wagtail.models import Page
from wagtail.snippets.models import register_snippet

from .forms import ContactForm
from .i18n import EDITABLE_TEXT_CHOICES, LANGUAGE_CHOICES, normalize_language, ui_for
from .security import (
    client_ip,
    consume_rate_limit,
    make_contact_form_token,
    rate_fingerprint,
    validate_contact_form_token,
)


logger = logging.getLogger(__name__)


class SecurityRateLimit(models.Model):
    """Skupni števec zlorab, brez shranjevanja surovega IP-ja ali vsebine."""

    scope = models.CharField(max_length=40)
    fingerprint = models.CharField(max_length=64)
    window_started_at = models.DateTimeField()
    count = models.PositiveIntegerField(default=0)
    blocked_until = models.DateTimeField(null=True, blank=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["scope", "fingerprint"],
                name="home_security_rate_scope_fingerprint_uniq",
            ),
        ]
        indexes = [models.Index(fields=["updated_at"], name="home_sec_rate_updated_idx")]

    def __str__(self):
        return f"{self.scope}: {self.fingerprint[:10]}…"


@register_setting
class OfficeSettings(BaseSiteSetting):
    v2_initialized = models.BooleanField(default=False, editable=False)
    maintenance_mode = models.BooleanField("Vklopi vzdrževalni način", default=False)
    maintenance_title = models.CharField("Naslov obvestila", max_length=160, default="Vzdrževalna dela")
    maintenance_message = RichTextField("Obvestilo obiskovalcem", default=(
        "<p>Spletno stran trenutno posodabljamo. Za nujne zadeve nas pokličite ali nam pišite.</p>"
    ))
    maintenance_title_en = models.CharField("Naslov obvestila – EN", max_length=160, blank=True)
    maintenance_message_en = RichTextField("Obvestilo obiskovalcem – EN", blank=True)
    maintenance_title_hr = models.CharField("Naslov obvestila – HR", max_length=160, blank=True)
    maintenance_message_hr = RichTextField("Obvestilo obiskovalcem – HR", blank=True)
    maintenance_title_de = models.CharField("Naslov obvestila – DE", max_length=160, blank=True)
    maintenance_message_de = RichTextField("Obvestilo obiskovalcem – DE", blank=True)
    office_name = models.CharField("Naziv pisarne", max_length=160, default="Odvetniška pisarna Weindorfer")
    brand_top_line = models.CharField("Zgornja vrstica podpisa", max_length=120, default="ODVETNIŠKA PISARNA")
    brand_bottom_line = models.CharField("Spodnja vrstica podpisa", max_length=120, default="WEINDORFER")
    address = models.CharField("Naslov", max_length=160, default="Slomškova ulica 9")
    postal_city = models.CharField("Poštna številka in kraj", max_length=160, default="9000 Murska Sobota")
    phone = models.CharField("Telefon", max_length=80, default="+386 (0)2 534 10 00")
    phone_link = models.CharField("Telefon za povezavo", max_length=40, default="+38625341000")
    fax = models.CharField("Faks", max_length=80, default="+386 (0)2 534 10 01", blank=True)
    email = models.EmailField("E-pošta", default="info@odvetnik-weindorfer.si")
    tax_number = models.CharField("Davčna številka", max_length=80, default="SI 44832826")
    business_iban = models.CharField("Poslovni račun", max_length=80, default="SI56 0234 0026 1815 896", blank=True)
    fiduciary_iban = models.CharField("Fiduciarni račun", max_length=80, default="SI56 0234 0026 1816 090", blank=True)
    office_hours = RichTextField("Uradne ure", default=(
        "<p>Od ponedeljka do petka med 8. in 13. uro ter v ponedeljek "
        "popoldan med 15. in 17. uro.</p><p><strong>Izven uradnih ur stranke "
        "sprejemamo po predhodnem telefonskem naročilu ali po e-pošti.</strong></p>"
    ))
    office_hours_en = RichTextField("Uradne ure – EN", blank=True)
    office_hours_hr = RichTextField("Uradne ure – HR", blank=True)
    office_hours_de = RichTextField("Uradne ure – DE", blank=True)
    map_query = models.CharField("Naslov za zemljevid", max_length=220, default="Slomškova ulica 9, 9000 Murska Sobota")
    map_place_id = models.CharField(
        "Google Place ID (neobvezno)", max_length=220, blank=True,
        help_text="Za povsem natančen žebljiček. Če je prazno, se uporabi naslov.",
    )
    footer_badge_text = models.TextField("Besedilo ob oznaki ARAG", default=(
        "Kontaktni odvetnik ARAG-a\nSmo na seznamu izvajalcev brezplačne pravne pomoči."
    ))
    footer_badge_text_en = models.TextField("Besedilo ob oznaki ARAG – EN", blank=True)
    footer_badge_text_hr = models.TextField("Besedilo ob oznaki ARAG – HR", blank=True)
    footer_badge_text_de = models.TextField("Besedilo ob oznaki ARAG – DE", blank=True)

    panels = [
        MultiFieldPanel([
            FieldPanel("maintenance_mode"), FieldPanel("maintenance_title"), FieldPanel("maintenance_message"),
        ], heading="Vzdrževalni način"),
        MultiFieldPanel([
            FieldPanel("maintenance_title_en"), FieldPanel("maintenance_message_en"),
            FieldPanel("maintenance_title_hr"), FieldPanel("maintenance_message_hr"),
            FieldPanel("maintenance_title_de"), FieldPanel("maintenance_message_de"),
        ], heading="Vzdrževalni način – prevodi"),
        MultiFieldPanel([
            FieldPanel("office_name"), FieldPanel("brand_top_line"), FieldPanel("brand_bottom_line"),
            FieldPanel("address"), FieldPanel("postal_city"),
            FieldPanel("tax_number"), FieldPanel("business_iban"), FieldPanel("fiduciary_iban"),
        ], heading="Podatki pisarne"),
        MultiFieldPanel([
            FieldPanel("phone"), FieldPanel("phone_link"), FieldPanel("fax"), FieldPanel("email"),
        ], heading="Kontakt"),
        MultiFieldPanel([
            FieldPanel("office_hours"), FieldPanel("office_hours_en"),
            FieldPanel("office_hours_hr"), FieldPanel("office_hours_de"),
        ], heading="Uradne ure in prevodi"),
        MultiFieldPanel([FieldPanel("map_query"), FieldPanel("map_place_id")], heading="Zemljevid in navodila za pot"),
        MultiFieldPanel([
            FieldPanel("footer_badge_text"), FieldPanel("footer_badge_text_en"),
            FieldPanel("footer_badge_text_hr"), FieldPanel("footer_badge_text_de"),
        ], heading="Oznake v nogi in prevodi"),
    ]

    class Meta:
        verbose_name = "Podatki odvetniške pisarne"

    @property
    def map_destination(self):
        return f"place_id:{self.map_place_id}" if self.map_place_id else self.map_query

    def localized(self, field_name, language_code):
        language = normalize_language(language_code)
        translated = getattr(self, f"{field_name}_{language}", "") if language != "sl" else ""
        return translated or getattr(self, field_name)


@register_snippet
class MenuItem(models.Model):
    ANCHORS = [
        ("o-nas", "O nas"),
        ("podrocja", "Področja dela"),
        ("odvetnik", "Odvetnik"),
        ("bpp", "Brezplačna pravna pomoč"),
        ("lokacija", "Kako do nas"),
        ("kontakt", "Kontakt"),
    ]

    anchor = models.CharField("Ciljni razdelek", max_length=40, choices=ANCHORS, unique=True)
    label_sl = models.CharField("Naziv – SL", max_length=120)
    label_en = models.CharField("Naziv – EN", max_length=120, blank=True)
    label_hr = models.CharField("Naziv – HR", max_length=120, blank=True)
    label_de = models.CharField("Naziv – DE", max_length=120, blank=True)
    active = models.BooleanField("Prikaži v meniju", default=True)
    sort_order = models.PositiveSmallIntegerField("Vrstni red", default=0)

    panels = [
        FieldPanel("anchor"),
        MultiFieldPanel([
            FieldPanel("label_sl"), FieldPanel("label_en"),
            FieldPanel("label_hr"), FieldPanel("label_de"),
        ], heading="Nazivi v meniju"),
        FieldPanel("active"), FieldPanel("sort_order"),
    ]

    class Meta:
        ordering = ["sort_order", "id"]
        verbose_name = "Element glavnega menija"
        verbose_name_plural = "Glavni meni"

    def localized_label(self, language_code):
        language = normalize_language(language_code)
        return getattr(self, f"label_{language}", "") or self.label_sl

    def __str__(self):
        return self.label_sl


@register_snippet
class EditableText(models.Model):
    key = models.CharField("Mesto besedila", max_length=80, choices=EDITABLE_TEXT_CHOICES, unique=True)
    text_sl = models.CharField("Besedilo – SL", max_length=240)
    text_en = models.CharField("Besedilo – EN", max_length=240, blank=True)
    text_hr = models.CharField("Besedilo – HR", max_length=240, blank=True)
    text_de = models.CharField("Besedilo – DE", max_length=240, blank=True)

    panels = [
        FieldPanel("key"),
        MultiFieldPanel([
            FieldPanel("text_sl"), FieldPanel("text_en"),
            FieldPanel("text_hr"), FieldPanel("text_de"),
        ], heading="Besedilo v vseh jezikih"),
    ]

    class Meta:
        ordering = ["key"]
        verbose_name = "Kratko besedilo strani"
        verbose_name_plural = "Kratka besedila strani"

    def localized_text(self, language_code):
        language = normalize_language(language_code)
        return getattr(self, f"text_{language}", "") or self.text_sl

    def __str__(self):
        return self.get_key_display()


@register_snippet
class PracticeArea(models.Model):
    language_code = models.CharField(
        "Jezik", max_length=8, choices=LANGUAGE_CHOICES, default="sl", db_index=True,
    )
    title = models.CharField("Naslov področja", max_length=160)
    items = RichTextField("Storitve")
    sort_order = models.PositiveSmallIntegerField("Vrstni red", default=0)

    panels = [FieldPanel("language_code"), FieldPanel("title"), FieldPanel("items"), FieldPanel("sort_order")]

    class Meta:
        ordering = ["language_code", "sort_order", "title"]
        constraints = [
            models.UniqueConstraint(
                fields=["language_code", "title"], name="home_practice_language_title_uniq",
            ),
        ]
        verbose_name = "Področje dela"
        verbose_name_plural = "Področja dela"

    def __str__(self):
        return self.title


@register_snippet
class Lawyer(models.Model):
    language_code = models.CharField(
        "Jezik", max_length=8, choices=LANGUAGE_CHOICES, default="sl", db_index=True,
    )
    name = models.CharField("Ime in naziv", max_length=180)
    role = models.CharField("Funkcija", max_length=100, default="odvetnik")
    photo = models.ForeignKey(
        "wagtailimages.Image", verbose_name="Fotografija", null=True, blank=True,
        on_delete=models.SET_NULL, related_name="+",
    )
    phone = models.CharField("Telefon", max_length=80, blank=True)
    phone_link = models.CharField("Telefon za povezavo", max_length=40, blank=True)
    mobile = models.CharField("Mobilni telefon", max_length=80, blank=True)
    mobile_link = models.CharField("Mobilni telefon za povezavo", max_length=40, blank=True)
    email = models.EmailField("E-pošta", blank=True)
    education = RichTextField("Izobrazba", blank=True)
    experience = RichTextField("Delovne izkušnje", blank=True)
    introduction = models.TextField("Kratek uvod", blank=True)
    biography = RichTextField("Predstavitev odvetnika", blank=True)
    work_style = RichTextField("Način dela", blank=True)
    languages = RichTextField("Jeziki in mednarodne zadeve", blank=True)
    sort_order = models.PositiveSmallIntegerField("Vrstni red", default=0)

    panels = [
        FieldPanel("language_code"), FieldPanel("name"), FieldPanel("role"), FieldPanel("photo"),
        MultiFieldPanel([
            FieldPanel("phone"), FieldPanel("phone_link"), FieldPanel("mobile"),
            FieldPanel("mobile_link"), FieldPanel("email"),
        ], heading="Kontakt"),
        FieldPanel("introduction"), FieldPanel("biography"), FieldPanel("education"),
        FieldPanel("experience"), FieldPanel("work_style"), FieldPanel("languages"),
        FieldPanel("sort_order"),
    ]

    class Meta:
        ordering = ["language_code", "sort_order", "name"]
        constraints = [
            models.UniqueConstraint(
                fields=["language_code", "name"], name="home_lawyer_language_name_uniq",
            ),
        ]
        verbose_name = "Odvetnik"
        verbose_name_plural = "Odvetniki"

    def __str__(self):
        return self.name


@register_snippet
class UsefulLink(models.Model):
    GROUPS = [
        ("Sodišča", "Sodišča"),
        ("Zakonodaja", "Zakonodaja"),
        ("Uporabne povezave", "Uporabne povezave"),
        ("Organi in zbornice", "Organi in zbornice"),
    ]
    group = models.CharField("Skupina", max_length=80, choices=GROUPS)
    label = models.CharField("Naziv povezave", max_length=180)
    url = models.URLField("Spletni naslov", max_length=500)
    sort_order = models.PositiveSmallIntegerField("Vrstni red", default=0)

    panels = [FieldPanel("group"), FieldPanel("label"), FieldPanel("url"), FieldPanel("sort_order")]

    class Meta:
        ordering = ["sort_order", "label"]
        verbose_name = "Spletna povezava"
        verbose_name_plural = "Spletne povezave"

    def __str__(self):
        return self.label


@register_snippet
class HeaderSlide(models.Model):
    title = models.CharField("Naziv fotografije", max_length=160)
    image = models.ForeignKey(
        "wagtailimages.Image", verbose_name="Fotografija", on_delete=models.CASCADE, related_name="+",
    )
    alt_text = models.CharField(
        "Opis slike za slepe in slabovidne", max_length=220, blank=True,
        help_text="Kratek vsebinski opis. Če je fotografija le dekorativna, lahko ostane prazno.",
    )
    active = models.BooleanField("Prikaži v vrtiljaku", default=True)
    sort_order = models.PositiveSmallIntegerField("Vrstni red", default=0)

    panels = [
        FieldPanel("title"), FieldPanel("image"), FieldPanel("alt_text"),
        FieldPanel("active"), FieldPanel("sort_order"),
    ]

    class Meta:
        ordering = ["sort_order", "title"]
        verbose_name = "Naslovna fotografija"
        verbose_name_plural = "Naslovne fotografije"

    def __str__(self):
        return self.title


class HomePage(Page):
    intro = RichTextField("Predstavitev", blank=True)
    hero_image = models.ForeignKey(
        "wagtailimages.Image", verbose_name="Naslovna fotografija", null=True, blank=True,
        on_delete=models.SET_NULL, related_name="+",
    )
    hero_eyebrow = models.CharField("Nadnaslov naslovnice", max_length=180, blank=True)
    hero_title = models.CharField("Glavni naslov", max_length=240, blank=True)
    hero_lead = models.TextField("Uvod naslovnice", blank=True)
    trust_points = RichTextField("Poudarki pod naslovnico", blank=True)
    about_eyebrow = models.CharField("Nadnaslov predstavitve", max_length=120, blank=True)
    about_title = models.CharField("Naslov predstavitve", max_length=240, blank=True)
    about_image = models.ForeignKey(
        "wagtailimages.Image", verbose_name="Fotografija v predstavitvi", null=True, blank=True,
        on_delete=models.SET_NULL, related_name="+",
    )
    about_image_alt = models.CharField(
        "Opis fotografije za slepe in slabovidne", max_length=220, blank=True,
        help_text="Kratek vsebinski opis. Če je fotografija le dekorativna, lahko ostane prazno.",
    )
    practices_eyebrow = models.CharField("Nadnaslov področij dela", max_length=120, blank=True)
    practices_title = models.CharField("Naslov področij dela", max_length=240, blank=True)
    practices_intro = models.TextField("Uvod področij dela", blank=True)
    practices_search_text = RichTextField("Dodatno besedilo področij dela", blank=True)
    lawyer_eyebrow = models.CharField("Nadnaslov odvetnika", max_length=120, blank=True)
    cta_eyebrow = models.CharField("Nadnaslov poziva", max_length=120, blank=True)
    cta_title = models.CharField("Naslov poziva", max_length=220, blank=True)
    cta_text = models.TextField("Besedilo poziva", blank=True)
    contact_eyebrow = models.CharField("Nadnaslov kontakta", max_length=120, blank=True)
    contact_title = models.CharField("Naslov kontakta", max_length=220, blank=True)
    contact_intro = models.TextField("Uvod kontakta", blank=True)

    parent_page_types = []
    subpage_types = ["home.ContentPage", "home.ContactPage"]
    content_panels = Page.content_panels + [
        MultiFieldPanel([
            FieldPanel("hero_image"), FieldPanel("hero_eyebrow"), FieldPanel("hero_title"),
            FieldPanel("hero_lead"), FieldPanel("trust_points"),
        ], heading="Naslovnica"),
        MultiFieldPanel([
            FieldPanel("about_eyebrow"), FieldPanel("about_title"), FieldPanel("intro"),
            FieldPanel("about_image"), FieldPanel("about_image_alt"),
        ], heading="O pisarni"),
        MultiFieldPanel([
            FieldPanel("practices_eyebrow"), FieldPanel("practices_title"),
            FieldPanel("practices_intro"), FieldPanel("practices_search_text"),
        ], heading="Področja dela"),
        FieldPanel("lawyer_eyebrow"),
        MultiFieldPanel([
            FieldPanel("cta_eyebrow"), FieldPanel("cta_title"), FieldPanel("cta_text"),
        ], heading="Poziv k stiku"),
        MultiFieldPanel([
            FieldPanel("contact_eyebrow"), FieldPanel("contact_title"), FieldPanel("contact_intro"),
        ], heading="Kontakt"),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context["office"] = OfficeSettings.for_request(request)
        language = normalize_language(self.locale.language_code)
        context["practice_areas"] = PracticeArea.objects.filter(language_code=language)
        context["lawyers"] = Lawyer.objects.filter(language_code=language).select_related("photo")
        context["contact_page"] = ContactPage.objects.child_of(self).live().first()
        context["contact_form"] = ContactForm(
            language_code=language,
            initial={"form_token": make_contact_form_token()},
        )
        context["turnstile_site_key"] = settings.TURNSTILE_SITE_KEY
        context["privacy_page"] = ContentPage.objects.child_of(self).filter(
            page_kind="privacy", live=True,
        ).first()
        return context


class ContentPage(Page):
    PAGE_KINDS = [
        ("standard", "Običajna vsebinska stran"),
        ("practices", "Področja dela"),
        ("lawyers", "Odvetniki"),
        ("location", "Lokacija"),
        ("links", "Spletne povezave"),
        ("legal_aid", "Brezplačna pravna pomoč"),
        ("privacy", "Zasebnost"),
    ]
    page_kind = models.CharField("Vrsta strani", max_length=30, choices=PAGE_KINDS, default="standard")
    body = RichTextField("Vsebina", blank=True)

    parent_page_types = ["home.HomePage"]
    subpage_types = []
    content_panels = Page.content_panels + [FieldPanel("page_kind"), FieldPanel("body")]

    def serve(self, request, *args, **kwargs):
        if self.page_kind == "legal_aid":
            home_url = self.get_parent().specific.get_url(request=request) or "/"
            return HttpResponsePermanentRedirect(f"{home_url}#bpp")
        return super().serve(request, *args, **kwargs)

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context["office"] = OfficeSettings.for_request(request)
        if self.page_kind == "practices":
            context["practice_areas"] = PracticeArea.objects.filter(language_code=self.locale.language_code)
        elif self.page_kind == "lawyers":
            context["lawyers"] = Lawyer.objects.filter(
                language_code=self.locale.language_code,
            ).select_related("photo")
        elif self.page_kind == "links":
            context["useful_links"] = UsefulLink.objects.all()
        return context


class ContactPage(Page):
    intro = RichTextField("Uvodno besedilo", blank=True)
    thank_you_text = RichTextField("Potrdilo po oddaji", default=(
        "<p>Hvala za vaše sporočilo. Odvetniška pisarna Weindorfer vas bo kontaktirala v najkrajšem možnem času.</p>"
    ))

    parent_page_types = ["home.HomePage"]
    subpage_types = []
    content_panels = Page.content_panels + [FieldPanel("intro"), FieldPanel("thank_you_text")]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context["office"] = OfficeSettings.for_request(request)
        language = normalize_language(self.locale.language_code)
        context["form"] = ContactForm(
            language_code=language,
            initial={"form_token": make_contact_form_token()},
        )
        context["turnstile_site_key"] = settings.TURNSTILE_SITE_KEY
        context["privacy_page"] = ContentPage.objects.child_of(self.get_parent()).filter(
            page_kind="privacy", live=True,
        ).first()
        return context

    @staticmethod
    def _client_ip(request):
        return client_ip(request)

    @staticmethod
    def _turnstile_valid(request):
        secret = settings.TURNSTILE_SECRET_KEY
        if not secret:
            return not settings.TURNSTILE_REQUIRED
        token = request.POST.get("cf-turnstile-response", "").strip()
        if not token or len(token) > 2048:
            return False
        data = urlencode({
            "secret": secret,
            "response": token,
            "remoteip": ContactPage._client_ip(request),
        }).encode()
        try:
            verification = Request(
                "https://challenges.cloudflare.com/turnstile/v0/siteverify",
                data=data,
                headers={"Content-Type": "application/x-www-form-urlencoded"},
            )
            # URL je nespremenljiva HTTPS-konstanta, ne uporabniški vnos.
            with urlopen(verification, timeout=6) as response:  # nosec B310
                result = json.load(response)
            if not result.get("success"):
                return False
            hostname = str(result.get("hostname", "")).lower().rstrip(".")
            expected_hosts = {host.lower().rstrip(".") for host in settings.TURNSTILE_EXPECTED_HOSTNAMES}
            if expected_hosts and hostname not in expected_hosts:
                logger.warning("Turnstile je vrnil nepričakovano gostiteljsko ime")
                return False
            expected_action = settings.TURNSTILE_EXPECTED_ACTION
            if expected_action and result.get("action") != expected_action:
                logger.warning("Turnstile je vrnil nepričakovano dejanje")
                return False
            return True
        except Exception:
            logger.exception("Preverjanje Turnstile ni uspelo")
            return False

    def serve(self, request, *args, **kwargs):
        context = self.get_context(request)
        if request.method != "POST":
            return render(request, self.get_template(request), context)

        language = normalize_language(self.locale.language_code)
        ui = ui_for(language)
        form = ContactForm(request.POST, language_code=language)
        context["form"] = form
        if not form.is_valid():
            return render(request, self.get_template(request), context, status=400)

        if form.cleaned_data.get("website"):
            context["submitted"] = True
            return render(request, self.get_template(request), context)

        if not validate_contact_form_token(form.cleaned_data.get("form_token", "")):
            context["send_error"] = ui["form_expired"]
            return render(request, self.get_template(request), context, status=400)

        ip = self._client_ip(request)
        short_limit = consume_rate_limit(
            "contact-short",
            rate_fingerprint("contact", ip),
            settings.CONTACT_RATE_SHORT_LIMIT,
            settings.CONTACT_RATE_SHORT_SECONDS,
            settings.CONTACT_RATE_SHORT_SECONDS,
        )
        daily_limit = consume_rate_limit(
            "contact-daily",
            rate_fingerprint("contact", ip),
            settings.CONTACT_RATE_DAILY_LIMIT,
            settings.CONTACT_RATE_DAILY_SECONDS,
            settings.CONTACT_RATE_DAILY_SECONDS,
        )
        if not short_limit.allowed or not daily_limit.allowed:
            retry_after = max(short_limit.retry_after, daily_limit.retry_after)
            logger.warning("Blokirana prepogosta oddaja kontaktnega obrazca (%s)", rate_fingerprint(ip)[:12])
            context["send_error"] = ui["form_limited"]
            response = render(request, self.get_template(request), context, status=429)
            response["Retry-After"] = str(retry_after)
            return response

        if not self._turnstile_valid(request):
            logger.warning("Neuspešno Turnstile preverjanje kontaktnega obrazca (%s)", rate_fingerprint(ip)[:12])
            context["send_error"] = ui["form_captcha"]
            return render(request, self.get_template(request), context, status=400)

        office = context["office"]
        recipient = settings.CONTACT_RECIPIENT or office.email
        cleaned = form.cleaned_data
        message = (
            f"Ime in priimek: {cleaned['name']}\n"
            f"E-pošta: {cleaned['email']}\n"
            f"Telefon: {cleaned.get('phone') or '-'}\n\n"
            f"{cleaned['message']}"
        )
        email = EmailMessage(
            subject=f"[Spletna stran] {cleaned['subject']}",
            body=message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[recipient],
            reply_to=[cleaned["email"]],
        )
        try:
            email.send(fail_silently=False)
        except Exception:
            logger.exception("Kontaktnega sporočila ni bilo mogoče poslati")
            context["send_error"] = ui["form_send_error"]
            return render(request, self.get_template(request), context, status=503)

        context["submitted"] = True
        context["form"] = ContactForm(
            language_code=language,
            initial={"form_token": make_contact_form_token()},
        )
        return render(request, self.get_template(request), context)
