# core/recaptcha.py
"""
Google reCAPTCHA v2 verification utility.

Usage:
    from core.recaptcha import verify_recaptcha
    ok = verify_recaptcha(token=request.POST.get('g-recaptcha-response'), remote_ip=request.META.get('REMOTE_ADDR'))

Returns True  → token is valid (or keys not configured → graceful pass-through)
Returns False → token is invalid / expired / missing
"""

import json
import logging
import urllib.parse
import urllib.request

logger = logging.getLogger(__name__)

RECAPTCHA_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify'


def verify_recaptcha(token: str, remote_ip: str = None) -> bool:
    """
    Verify a reCAPTCHA v2 response token against Google's API.

    Gracefully returns True if:
      - reCAPTCHA is not enabled in SiteConfiguration
      - Secret key is not configured
      - Any network/timeout error occurs (fail-open to avoid blocking legit users)

    Returns False if:
      - Token is missing or empty
      - Google returns success=false
    """
    try:
        from core.models import SiteConfiguration
        cfg = SiteConfiguration.get_solo()

        # Not enabled or keys not configured → pass through
        if not cfg.recaptcha_enabled:
            return True
        if not cfg.recaptcha_secret_key or not cfg.recaptcha_site_key:
            logger.warning(
                'reCAPTCHA is enabled but keys are not configured. '
                'Skipping verification. Configure keys in Django Admin → Site Configuration.'
            )
            return True
        secret = cfg.recaptcha_secret_key
    except Exception as exc:
        logger.error('reCAPTCHA: failed to load SiteConfiguration: %s', exc)
        return True  # Fail open — don't block users on DB errors

    if not token:
        return False

    try:
        payload = {
            'secret': secret,
            'response': token,
        }
        if remote_ip:
            payload['remoteip'] = remote_ip

        data = urllib.parse.urlencode(payload).encode('utf-8')
        req  = urllib.request.Request(RECAPTCHA_VERIFY_URL, data=data, method='POST')

        with urllib.request.urlopen(req, timeout=5) as resp:
            result = json.loads(resp.read().decode('utf-8'))

        if not result.get('success', False):
            logger.info('reCAPTCHA verification failed: %s', result.get('error-codes', []))
            return False

        return True

    except Exception as exc:
        # Network errors, timeouts → fail open rather than locking out legit users
        logger.error('reCAPTCHA: verification request failed: %s', exc)
        return True
