import logging

import requests
from django import forms
from django.utils.translation import gettext_lazy as _

from .conf import get_setting
from .constants import SITE_VERIFY_URL
from .widgets import InvisibleRecaptchaWidget

__title__ = (
    "fobi.contrib.plugins.form_elements.security." "invisible_recaptcha.fields"
)
__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
__copyright__ = "2014-2019 Artur Barseghyan"
__license__ = "GPL 2.0/LGPL 2.1"
__all__ = ("InvisibleRecaptchaField",)

LOGGER = logging.getLogger(__name__)


class InvisibleRecaptchaField(forms.CharField):
    """Invisible reCAPTCHA field"""

    default_error_messages = {
        "invalid": _("Field value was tampered with."),
        "validation_error": _("Invisible reCAPTCHA validation error"),
        "incorrect_captcha": _("Incorrect CAPTCHA, please try again"),
    }
    widget = InvisibleRecaptchaWidget

    def __init__(self, recaptcha_response=None, *args, **kwargs):
        self.recaptcha_response = recaptcha_response
        super(InvisibleRecaptchaField, self).__init__(*args, **kwargs)

    def clean(self, value):
        """Validation."""

        site_secret = get_setting("SITE_SECRET")

        if not (site_secret and self.recaptcha_response):
            raise forms.ValidationError(
                self.error_messages["validation_error"], code="invalid"
            )

        response = requests.post(
            SITE_VERIFY_URL,
            data={
                "secret": site_secret,
                "response": self.recaptcha_response,
            },
        )

        if response.status_code != requests.codes.ok:
            LOGGER.error(
                "Invisible reCAPTCHA error: %s: %s",
                response.status_code,
                response.reason,
            )
            raise forms.ValidationError(
                self.error_messages["validation_error"], code="invalid"
            )
        else:
            response = response.json()

        error_codes = response.get("error-codes")
        if error_codes:
            LOGGER.error(
                "Invisible reCAPTCHA verification error: %s", error_codes
            )

        result = response.get("success")
        if result:
            LOGGER.info(response)
            return value

        raise forms.ValidationError(
            self.error_messages["incorrect_captcha"], code="invalid"
        )
