from __future__ import annotations

import httpx

from app.core.config import settings

VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify"


async def verify_recaptcha(
    token: str | None,
    expected_action: str | None = None,
    remote_ip: str | None = None,
) -> tuple[bool, str]:
    if not settings.RECAPTCHA_ENABLED or not (settings.RECAPTCHA_SECRET_KEY or "").strip():
        return True, "skipped"
    if not (token or "").strip():
        return False, "reCAPTCHA token is missing. Refresh the page and try again."

    payload = {
        "secret": settings.RECAPTCHA_SECRET_KEY.strip(),
        "response": token.strip(),
    }
    if remote_ip and remote_ip not in {"127.0.0.1", "::1", "localhost"}:
        payload["remoteip"] = remote_ip

    try:
        async with httpx.AsyncClient(timeout=10.0) as client:
            response = await client.post(VERIFY_URL, data=payload)
        response.raise_for_status()
        data = response.json()
    except Exception:
        return False, "Could not verify reCAPTCHA. Please try again."

    if not data.get("success"):
        codes = data.get("error-codes") or data.get("error_codes") or []
        if isinstance(codes, str):
            codes = [codes]
        if "invalid-input-secret" in codes:
            return False, "reCAPTCHA secret key is invalid. Check RECAPTCHA_SECRET_KEY in accounts_api/.env."
        if "invalid-input-response" in codes or "timeout-or-duplicate" in codes:
            return False, (
                "reCAPTCHA token was rejected. The API secret must belong to the same v3 key "
                "as VITE_RECAPTCHA_SITE_KEY. Update RECAPTCHA_SECRET_KEY and restart the API."
            )
        detail = ", ".join(str(code) for code in codes) if codes else "unknown error"
        return False, f"reCAPTCHA verification failed ({detail}). Use a matching reCAPTCHA v3 site key and secret."

    score = data.get("score")
    if score is None:
        return False, "reCAPTCHA verification failed. Use a reCAPTCHA v3 key pair, not v2 checkbox keys."
    if float(score) < float(settings.RECAPTCHA_MIN_SCORE):
        return False, "reCAPTCHA score is too low. Please try again."

    return True, "ok"
