"""
notifications.py - Multi-channel notification routing

Supported channels: Discord webhook, ntfy, Web Push
"""

import os
import core.postgres as postgres
import uuid
import requests
import time
import json
import logging

logger = logging.getLogger(__name__)


def _sendToEnabledChannels(notif_settings, message, user_uuid=None):
    """Send message to all enabled channels. Returns True if at least one succeeded."""
    sent = False

    if notif_settings.get("discord_enabled") and notif_settings.get("discord_user_id"):
        if discord.send_dm(notif_settings["discord_user_id"], message):
            sent = True

    if notif_settings.get("ntfy_enabled") and notif_settings.get("ntfy_topic"):
        if ntfy.send(notif_settings["ntfy_topic"], message):
            sent = True

    if notif_settings.get("web_push_enabled") and user_uuid:
        if web_push.send_to_user(user_uuid, message):
            sent = True

    return sent


def getNotificationSettings(userUUID):
    settings = postgres.select_one("notifications", {"user_uuid": userUUID})
    if not settings:
        return False
    return settings


def setNotificationSettings(userUUID, data_dict):
    existing = postgres.select_one("notifications", {"user_uuid": userUUID})
    allowed = [
        "discord_user_id",
        "discord_enabled",
        "ntfy_topic",
        "ntfy_enabled",
        "web_push_enabled",
    ]
    updates = {k: v for k, v in data_dict.items() if k in allowed}
    if not updates:
        return False
    if existing:
        postgres.update("notifications", updates, {"user_uuid": userUUID})
    else:
        updates["id"] = str(uuid.uuid4())
        updates["user_uuid"] = userUUID
        postgres.insert("notifications", updates)
    return True


class discord:
    @staticmethod
    def send_dm(user_id, message):
        """Send a DM to a Discord user via the bot."""
        bot_token = os.environ.get("DISCORD_BOT_TOKEN")
        if not bot_token:
            logger.warning("DISCORD_BOT_TOKEN not set, skipping Discord DM")
            return False
        headers = {"Authorization": f"Bot {bot_token}", "Content-Type": "application/json"}
        try:
            # Open/get DM channel with the user
            dm_resp = requests.post(
                "https://discord.com/api/v10/users/@me/channels",
                headers=headers,
                json={"recipient_id": user_id},
            )
            if dm_resp.status_code != 200:
                logger.error(f"Failed to open DM channel for user {user_id}: {dm_resp.status_code}")
                return False
            channel_id = dm_resp.json()["id"]
            # Send the message
            msg_resp = requests.post(
                f"https://discord.com/api/v10/channels/{channel_id}/messages",
                headers=headers,
                json={"content": message},
            )
            return msg_resp.status_code == 200
        except Exception as e:
            logger.error(f"Discord DM error: {e}")
            return False


class ntfy:
    @staticmethod
    def send(topic, message):
        try:
            response = requests.post(
                f"https://ntfy.sh/{topic}", data=message.encode("utf-8")
            )
            return response.status_code == 200
        except:
            return False


class web_push:
    @staticmethod
    def send_to_user(user_uuid, message):
        """Send web push notification to all subscriptions for a user."""
        try:
            from pywebpush import webpush, WebPushException

            vapid_private_key = os.environ.get("VAPID_PRIVATE_KEY")
            vapid_claims_email = os.environ.get("VAPID_CLAIMS_EMAIL", "mailto:admin@synculous.app")
            if not vapid_private_key:
                logger.warning("VAPID_PRIVATE_KEY not set, skipping web push")
                return False

            subscriptions = postgres.select("push_subscriptions", where={"user_uuid": user_uuid})
            if not subscriptions:
                return False

            payload = json.dumps({"title": "Synculous", "body": message})
            sent_any = False

            for sub in subscriptions:
                try:
                    webpush(
                        subscription_info={
                            "endpoint": sub["endpoint"],
                            "keys": {
                                "p256dh": sub["p256dh"],
                                "auth": sub["auth"],
                            },
                        },
                        data=payload,
                        vapid_private_key=vapid_private_key,
                        vapid_claims={"sub": vapid_claims_email},
                    )
                    sent_any = True
                except WebPushException as e:
                    # 410 Gone or 404 means subscription expired - clean up
                    if hasattr(e, "response") and e.response and e.response.status_code in (404, 410):
                        postgres.delete("push_subscriptions", {"id": sub["id"]})
                    else:
                        logger.error(f"Web push failed for subscription {sub['id']}: {e}")
                except Exception as e:
                    logger.error(f"Web push error: {e}")

            return sent_any
        except ImportError:
            logger.warning("pywebpush not installed, skipping web push")
            return False
        except Exception as e:
            logger.error(f"Web push send_to_user error: {e}")
            return False
