import json
from django.conf import settings
from django.http import JsonResponse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST, require_GET
from .models import NotificationEvent, OutboundSms, Device
from .sms import enqueue_sms


def _bearer(request):
    a = request.META.get("HTTP_AUTHORIZATION", "")
    return a[7:].strip() if a.startswith("Bearer ") else ""


@csrf_exempt
@require_POST
def email_arrived(request):
    if not settings.OPEMAILS_NOTIFY_SECRET or _bearer(request) != settings.OPEMAILS_NOTIFY_SECRET:
        return JsonResponse({"ok": False, "error": "unauthorized"}, status=401)
    try:
        data = json.loads(request.body.decode("utf-8") or "{}")
    except ValueError:
        return JsonResponse({"ok": False, "error": "bad json"}, status=400)

    evt = NotificationEvent.objects.create(
        event=data.get("event", "new_email"), mailbox=data.get("mailbox", "")[:190],
        mailbox_id=data.get("mailbox_id"), sender=data.get("from", "")[:320],
        subject=(data.get("subject") or "")[:500], preview=(data.get("preview") or "")[:200],
        source_ref=str(data.get("message_id") or "")[:64], payload=data,
    )
    body = f"{evt.mailbox}: {evt.sender}\n{evt.subject}"
    n = 0
    for phone in data.get("recipients", []):
        phone = (phone or "").strip()
        if phone:
            enqueue_sms(phone, body, event=evt); n += 1
    # TODO push: when the VAOne app ships, fan out to Device.push_token via FCM/APNs here.
    return JsonResponse({"ok": True, "event_id": evt.id, "sms_queued": n})


def _gateway_ok(request):
    return bool(settings.SMS_GATEWAY_KEY) and _bearer(request) == settings.SMS_GATEWAY_KEY


@csrf_exempt
@require_GET
def sms_pending(request):
    if not _gateway_ok(request):
        return JsonResponse({"ok": False, "error": "unauthorized"}, status=401)
    device, _ = Device.objects.get_or_create(
        device_id=request.GET.get("device", "gateway"),
        defaults={"is_sms_gateway": True, "platform": "android"})
    device.last_seen, device.is_sms_gateway = timezone.now(), True
    device.save(update_fields=["last_seen", "is_sms_gateway"])

    out = []
    for job in OutboundSms.objects.filter(status=OutboundSms.QUEUED, backend="ownsim").order_by("created_at")[:20]:
        job.status, job.device = OutboundSms.PICKED, device
        job.save(update_fields=["status", "device"])
        out.append({"id": job.id, "to": job.to_number, "body": job.body})
    return JsonResponse({"ok": True, "messages": out})


@csrf_exempt
@require_POST
def sms_result(request):
    if not _gateway_ok(request):
        return JsonResponse({"ok": False, "error": "unauthorized"}, status=401)
    try:
        data = json.loads(request.body.decode("utf-8") or "{}")
    except ValueError:
        return JsonResponse({"ok": False, "error": "bad json"}, status=400)
    try:
        job = OutboundSms.objects.get(id=data.get("id"))
    except OutboundSms.DoesNotExist:
        return JsonResponse({"ok": False, "error": "not found"}, status=404)
    ok = bool(data.get("success"))
    job.status = OutboundSms.SENT if ok else OutboundSms.FAILED
    job.error = (data.get("error") or "")[:500]; job.attempts += 1
    if ok: job.sent_at = timezone.now()
    job.save(update_fields=["status", "error", "attempts", "sent_at"])
    return JsonResponse({"ok": True})