"""
Notifications API - Web push subscription management and VAPID key endpoint
"""

import os
import uuid

import flask
import jwt
import core.auth as auth
import core.postgres as postgres
import core.notifications as notifications


def _get_user_uuid(token):
    try:
        payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
        return payload.get("sub")
    except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
        return None


def _auth(request):
    """Extract and verify token. Returns user_uuid or None."""
    header = request.headers.get("Authorization", "")
    if not header.startswith("Bearer "):
        return None
    token = header[7:]
    user_uuid = _get_user_uuid(token)
    if not user_uuid or not auth.verifyLoginToken(token, userUUID=user_uuid):
        return None
    return user_uuid


def register(app):

    @app.route("/api/notifications/vapid-public-key", methods=["GET"])
    def api_vapidPublicKey():
        """Return the VAPID public key for push subscription."""
        key = os.environ.get("VAPID_PUBLIC_KEY")
        if not key:
            return flask.jsonify({"error": "VAPID not configured"}), 503
        return flask.jsonify({"public_key": key}), 200

    @app.route("/api/notifications/subscribe", methods=["POST"])
    def api_pushSubscribe():
        """Register a push subscription. Body: {endpoint, keys: {p256dh, auth}}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        data = flask.request.get_json()
        if not data:
            return flask.jsonify({"error": "missing body"}), 400

        endpoint = data.get("endpoint")
        keys = data.get("keys", {})
        p256dh = keys.get("p256dh")
        auth_key = keys.get("auth")

        if not endpoint or not p256dh or not auth_key:
            return flask.jsonify({"error": "missing endpoint or keys"}), 400

        # Upsert: remove existing subscription with same endpoint for this user
        existing = postgres.select("push_subscriptions", where={
            "user_uuid": user_uuid,
            "endpoint": endpoint,
        })
        if existing:
            postgres.delete("push_subscriptions", {"id": existing[0]["id"]})

        row = {
            "id": str(uuid.uuid4()),
            "user_uuid": user_uuid,
            "endpoint": endpoint,
            "p256dh": p256dh,
            "auth": auth_key,
        }
        postgres.insert("push_subscriptions", row)
        # Ensure web_push_enabled is set in notifications settings
        notifications.setNotificationSettings(user_uuid, {"web_push_enabled": True})
        return flask.jsonify({"subscribed": True}), 201

    @app.route("/api/notifications/settings", methods=["GET"])
    def api_getNotificationSettings():
        """Return notification channel settings for the current user."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        settings = notifications.getNotificationSettings(user_uuid)
        if not settings:
            return flask.jsonify({
                "discord_user_id": "",
                "discord_enabled": False,
                "ntfy_topic": "",
                "ntfy_enabled": False,
                "web_push_enabled": False,
            }), 200
        return flask.jsonify({
            "discord_user_id": settings.get("discord_user_id") or "",
            "discord_enabled": bool(settings.get("discord_enabled")),
            "ntfy_topic": settings.get("ntfy_topic") or "",
            "ntfy_enabled": bool(settings.get("ntfy_enabled")),
            "web_push_enabled": bool(settings.get("web_push_enabled")),
        }), 200

    @app.route("/api/notifications/settings", methods=["PUT"])
    def api_updateNotificationSettings():
        """Update notification channel settings. Accepts partial updates."""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        data = flask.request.get_json()
        if not data:
            return flask.jsonify({"error": "missing body"}), 400
        result = notifications.setNotificationSettings(user_uuid, data)
        if not result:
            return flask.jsonify({"error": "no valid fields provided"}), 400
        return flask.jsonify({"updated": True}), 200

    @app.route("/api/notifications/subscribe", methods=["DELETE"])
    def api_pushUnsubscribe():
        """Remove a push subscription. Body: {endpoint}"""
        user_uuid = _auth(flask.request)
        if not user_uuid:
            return flask.jsonify({"error": "unauthorized"}), 401
        data = flask.request.get_json()
        if not data or not data.get("endpoint"):
            return flask.jsonify({"error": "missing endpoint"}), 400

        postgres.delete("push_subscriptions", {
            "user_uuid": user_uuid,
            "endpoint": data["endpoint"],
        })
        # If no subscriptions remain, disable web push
        remaining = postgres.select("push_subscriptions", where={"user_uuid": user_uuid})
        if not remaining:
            notifications.setNotificationSettings(user_uuid, {"web_push_enabled": False})
        return flask.jsonify({"unsubscribed": True}), 200
