"""
Service PayTech : demande de paiement et vérification IPN.
Toutes les requêtes vers PayTech passent par le backend (clés secrètes).
"""
import hashlib
import json
import os
import logging
import requests
from django.conf import settings


logger = logging.getLogger(__name__)


def _get_config():
    return {
        "api_key": getattr(settings, "PAYTECH_API_KEY", "") or os.environ.get("PAYTECH_API_KEY", ""),
        "api_secret": getattr(settings, "PAYTECH_API_SECRET", "") or os.environ.get("PAYTECH_API_SECRET", ""),
        "env": getattr(settings, "PAYTECH_ENV", "test") or os.environ.get("PAYTECH_ENV", "test"),
        "success_url": settings.PAYTECH_SUCCESS_URL,
        "cancel_url": settings.PAYTECH_CANCEL_URL,
        "ipn_url": settings.PAYTECH_IPN_URL,
    }


BASE_URL = "https://paytech.sn/api"


def request_payment(*, item_name, item_price, ref_command, custom_field=None, user, document_type=None):
    """
    Crée une demande de paiement PayTech.
    document_type (bp/bmc/pitch) est ajouté aux URLs de redirection pour la page succès/annulation.
    """
    config = _get_config()
    has_keys = bool(config["api_key"]) and bool(config["api_secret"])
    logger.info(
        "PAYTECH request_payment user=%s type=%s amount=%s env=%s success_url=%s cancel_url=%s ipn_url=%s has_keys=%s",
        getattr(user, "id", None),
        document_type,
        item_price,
        config["env"],
        config["success_url"],
        config["cancel_url"],
        config["ipn_url"],
        has_keys,
    )

    if not has_keys:
        return {"success": 0, "message": "PayTech non configuré (clés API manquantes)."}

    # Log brut des URLs lues depuis la config (pour debug "successRedirectUrl doit être un URL")
    raw_success = (config.get("success_url") or "").strip()
    raw_cancel = (config.get("cancel_url") or "").strip()
    raw_ipn = (config.get("ipn_url") or "").strip()

    def _log(msg):
        logger.info("%s", msg)
        print("[PAYTECH]", msg)

    _log(f"URLs brutes: success={raw_success!r} cancel={raw_cancel!r} ipn={raw_ipn!r}")
    if not raw_success or not raw_cancel:
        _log("ATTENTION: success_url ou cancel_url vide -> risque erreur PayTech 'successRedirectUrl doit être un URL'")

    sep = "&" if "?" in raw_success else "?"
    success_url = f"{raw_success}{sep}document_type={document_type or ''}"
    cancel_url = f"{raw_cancel}{sep}document_type={document_type or ''}"

    _log(f"URLs finales envoyées: success_url={success_url!r} cancel_url={cancel_url!r}")

    payload = {
        "item_name": item_name,
        "item_price": item_price,
        "currency": "XOF",
        "ref_command": ref_command,
        "command_name": item_name,
        "env": config["env"],
        "success_url": success_url,
        "cancel_url": cancel_url,
        "ipn_url": raw_ipn,
        "target_payment": "Orange Money, Wave, Free Money",
    }
    if custom_field is not None:
        payload["custom_field"] = json.dumps(custom_field) if isinstance(custom_field, dict) else str(custom_field)

    payload_log = {k: v for k, v in payload.items() if k != "custom_field"}
    _log(f"Payload envoyé (sans custom_field): {payload_log}")

    try:
        request_url = f"{BASE_URL}/payment/request-payment"
        _log(f"POST {request_url} success_url_in_body={payload.get('success_url')!r}")
        response = requests.post(
            request_url,
            json=payload,
            headers={
                "API_KEY": config["api_key"],
                "API_SECRET": config["api_secret"],
            },
            timeout=15,
        )
        raw_text = response.text
        _log(f"Response PayTech: status={response.status_code} body_len={len(raw_text)}")
        try:
            data = response.json()
        except Exception as parse_err:
            _log(f"ERREUR parse JSON: {parse_err} raw={raw_text[:300]}")
            return {"success": 0, "message": f"Réponse PayTech invalide: {parse_err}"}
        _log(f"Response body: success={data.get('success')} token={data.get('token')} redirect_url={data.get('redirect_url') or data.get('redirectUrl')}")
        if data.get("success") != 1 and data.get("message"):
            _log(f"Message erreur PayTech: {data.get('message')}")
    except requests.RequestException as e:
        logger.exception("PAYTECH request_payment exception")
        return {"success": 0, "message": str(e)}

    if response.status_code in (200, 201) and data.get("success") == 1:
        redirect = data.get("redirect_url") or data.get("redirectUrl") or ""
        return {"success": 1, "redirect_url": redirect, "token": data.get("token", "")}
    return {"success": 0, "message": data.get("message", "Erreur PayTech")}


def verify_ipn(request):
    """
    Vérifie l'authenticité de la notification IPN PayTech (POST).
    PayTech envoie api_key_sha256 et api_secret_sha256.
    """
    config = _get_config()
    api_key_sha256 = request.POST.get("api_key_sha256", "")
    api_secret_sha256 = request.POST.get("api_secret_sha256", "")

    expected_key = hashlib.sha256(config["api_key"].encode()).hexdigest()
    expected_secret = hashlib.sha256(config["api_secret"].encode()).hexdigest()

    return api_key_sha256 == expected_key and api_secret_sha256 == expected_secret
