# retoor <retoor@molodetz.nl>

import logging
from fastapi import APIRouter, Request
from fastapi.responses import FileResponse, JSONResponse
from devplacepy import push
from devplacepy.config import STATIC_DIR
from devplacepy.push import providers
from devplacepy.utils import require_user_api
from urllib.parse import urlparse
from devplacepy.services.audit import record as audit

logger = logging.getLogger(__name__)
router = APIRouter()

WELCOME_PAYLOAD = {
    "title": "DevPlace",
    "message": "Push notifications enabled.",
    "icon": "/static/apple-touch-icon.png",
    "url": "/notifications",
}


@router.get("/push.json")
async def push_public_key() -> JSONResponse:
    configs = providers.client_config()
    webpush = configs.get(providers.DEFAULT_PROVIDER, {})
    return JSONResponse(
        {"publicKey": webpush.get("publicKey", ""), "providers": configs}
    )


@router.post("/push.json")
async def push_register(request: Request) -> JSONResponse:
    user = require_user_api(request)
    try:
        body = await request.json()
    except ValueError:
        return JSONResponse({"error": "Invalid JSON"}, status_code=400)

    if not isinstance(body, dict):
        return JSONResponse({"error": "Invalid request"}, status_code=400)

    provider = providers.get(body.get("provider"))
    if provider is None or not providers.is_active(provider):
        return JSONResponse({"error": "Unknown provider"}, status_code=400)

    fields = provider.parse_registration(body)
    if fields is None:
        return JSONResponse({"error": "Invalid request"}, status_code=400)

    fields = provider.stamp_registration(fields)
    write = push.register(user["uid"], provider.name, fields)

    delivered = None
    detail = ""
    if write.probe:
        try:
            outcome = await push.notify_registration(write.record, WELCOME_PAYLOAD)
            delivered = outcome.status == providers.ACCEPTED
            detail = outcome.detail
        except Exception as exc:
            logger.warning("Welcome push failed for %s: %s", user["uid"], exc)
            delivered = False
            detail = str(exc)

    audit.record(
        request,
        "push.subscribe" if write.created else "push.update",
        user=user,
        target_type="user",
        target_uid=user["uid"],
        target_label=user.get("username"),
        metadata={
            "provider": provider.name,
            "endpoint_host": urlparse(fields["endpoint"]).hostname
            if fields.get("endpoint")
            else None,
            "created": write.created,
            "revived": write.revived,
            "has_client_id": bool(fields.get("client_id")),
        },
        summary=f"{user.get('username')} {'registered' if write.created else 'updated'} a push subscription",
        links=[audit.target("user", user["uid"], user.get("username"))],
    )
    payload: dict = {"registered": True}
    if delivered is not None:
        payload["delivered"] = delivered
        if detail and not delivered:
            payload["error"] = detail
    return JSONResponse(payload)


@router.get("/service-worker.js")
async def service_worker() -> FileResponse:
    return FileResponse(
        STATIC_DIR / "service-worker.js",
        media_type="application/javascript",
        headers={"Service-Worker-Allowed": "/", "Cache-Control": "no-cache"},
    )


@router.get("/manifest.json")
async def manifest() -> FileResponse:
    return FileResponse(
        STATIC_DIR / "manifest.json", media_type="application/manifest+json"
    )
