# pxy_messenger/views.py
import hashlib, hmac, json, logging, os
from django.conf import settings
from django.http import HttpResponse, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt

# Optional: if you created a model to dedupe events (you have one in admin!)
from .models import MessengerEvent  # keep if present

import requests

log = logging.getLogger(__name__)
GRAPH_API = os.getenv("META_GRAPH_API", "https://graph.facebook.com/v18.0")

def _verify_get(request):
    mode  = request.GET.get("hub.mode")
    token = request.GET.get("hub.verify_token")
    chal  = request.GET.get("hub.challenge", "")
    if mode == "subscribe" and token == getattr(settings, "MESSENGER_VERIFY_TOKEN", ""):
        return HttpResponse(chal)
    return HttpResponseForbidden("Bad verify token")

def _verify_signature(request):
    app_secret = getattr(settings, "FACEBOOK_APP_SECRET", "")
    if not app_secret:
        return True  # dev mode (no signature check)

    provided = request.headers.get("X-Hub-Signature-256", "")
    body     = request.body

    # keep a copy for troubleshooting
    try:
        with open("/tmp/m_sig_body.bin", "wb") as f:
            f.write(body)
    except Exception:
        pass

    calc_hex = hmac.new(app_secret.encode("utf-8"), body, hashlib.sha256).hexdigest()
    expected = "sha256=" + calc_hex
    log.info("[messenger] sig check: provided=%r expected=%r body_len=%d", provided, expected, len(body))
    return hmac.compare_digest(provided, expected)

def _send_text(psid: str, text: str) -> bool:
    token = getattr(settings, "PAGE_ACCESS_TOKEN", "")
    if not token:
        log.warning("[messenger] no PAGE_ACCESS_TOKEN; would send to %s: %s", psid, text)
        return False

    url = f"{GRAPH_API}/me/messages"
    params = {"access_token": token}
    payload = {
        "messaging_type": "RESPONSE",
        "recipient": {"id": psid},
        "message": {"text": text},
    }
    try:
        r = requests.post(url, params=params, json=payload, timeout=10)
        if r.status_code != 200:
            log.error("[messenger] Send API error %s: %s", r.status_code, r.text)
            return False
        log.info("[messenger] sent to %s ok: %s", psid, r.text)
        return True
    except Exception as e:
        log.exception("[messenger] Send API exception: %s", e)
        return False

@csrf_exempt
def webhook(request):
    if request.method == "GET":
        return _verify_get(request)

    if request.method != "POST":
        return HttpResponse(status=405)

    if not _verify_signature(request):
        return HttpResponseForbidden("Invalid signature")

    try:
        payload = json.loads(request.body.decode("utf-8") or "{}")
    except Exception:
        payload = {}
    log.info("[messenger] payload: %s", json.dumps(payload)[:2000])

    # Iterate entries and messaging events
    for entry in payload.get("entry", []):
        for m in entry.get("messaging", []):
            sender = (m.get("sender") or {}).get("id")
            recipient = (m.get("recipient") or {}).get("id")

            # dedupe by message mid when present
            mid = (m.get("message") or {}).get("mid") \
                  or (m.get("delivery") or {}).get("mids", [None])[0]
            if mid:
                # store if not seen (your admin shows MessengerEvent already)
                obj, created = MessengerEvent.objects.get_or_create(
                    mid=mid,
                    defaults={
                        "sender_id": sender or "",
                        "page_id": recipient or "",
                    },
                )
                if not created:
                    log.info("[messenger] duplicate mid %s — skipping", mid)
                    continue

            # Basic text echo
            if "message" in m and "text" in m["message"] and sender:
                txt = m["message"]["text"].strip()
                reply = f"You said: {txt}"
                _send_text(sender, reply)

    # must 200 quickly
    return HttpResponse("OK")
