/**
 * SignalR 通知模块
 * 处理服务器推送的通知消息
 */

import {dialog} from './dialog.js';
import {outPutSuccess, outPutInfo, outPutWarning, outPutError} from './console-logger.js';

/**
 * 更新连接状态指示器
 * @param {string} status - 连接状态 'connected' | 'disconnected' | 'reconnecting'
 */
function updateConnectionStatus(status) {
    const statusElement = document.getElementById('signalr-status');
    if (!statusElement) return;

    statusElement.classList.remove('connection-status--connected', 'connection-status--disconnected');

    switch (status) {
        case 'connected':
            statusElement.classList.add('connection-status--connected');
            statusElement.title = "消息服务:已连接";
            break;
        case 'disconnected':
            statusElement.classList.add('connection-status--disconnected');
            statusElement.title = "消息服务:已断开";
            break;
        case 'reconnecting':
            statusElement.classList.add('connection-status--disconnected');
            statusElement.title = "消息服务:正在重新连接...";
            break;
        default:
            statusElement.title = "消息服务:未连接";
            break;
    }
}

/**
 * 初始化主通知连接
 */
async function initMainNotification() {
    try {
        const connection = new signalR
            .HubConnectionBuilder()
            .withUrl("/notification", {
                skipNegotiation: true,
                transport: signalR.HttpTransportType.WebSockets,
            })
            .withAutomaticReconnect()
            .build();

        // 连接状态监控
        connection.onreconnecting(() => {
            console.warn("SignalR Reconnecting...");
            updateConnectionStatus('reconnecting');
        });

        connection.onreconnected(() => {
            console.info("SignalR Reconnected.");
            updateConnectionStatus('connected');
        });

        connection.onclose(() => {
            console.error("SignalR Disconnected.");
            updateConnectionStatus('disconnected');
        });

        await connection.start();
        updateConnectionStatus('connected');
        
        await connection.invoke("Init");

        // 推送消息通知
        connection.on("pushMessage", async function (result) {
            const option = {
                title: "小喇叭开始广播辣",
                content: result.markdown
            };
            const notification = await requestBrowserNotification(option);
            if (notification !== null) {
                notification.onclick = function () {
                    window.open("/mumble.html");
                };
            }
            console.info(result);
        });

        // 日志消息通知
        connection.on("pushLogMessage", function (type, message) {
            const timestamp = new Date().toLocaleString('zh-CN', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });

            if (type === 0) {
                // 成功
                outPutSuccess(message);
                dialog.toast(`${timestamp}\n${message}`, 'success');
            } else if (type === 1) {
                // 信息
                outPutInfo(message);
                dialog.toast(`${timestamp}\n${message}`, 'warning');
            } else if (type === 2) {
                // 错误
                outPutError(message);
                dialog.toast(`${timestamp}\n${message}`, 'error');
            }
        });

        // 订阅通知
        let newsPublishBox = null;
        const subscribeData = [];
        connection.on("cnBetaSubscribe", function (result) {
            const values = [];
            if (result.hasOwnProperty("progressValues") && Array.isArray(result["progressValues"])) {
                for (let i = 0; i < result["progressValues"].length; i++) {
                    const value = (result["progressValues"][i] * 100).toFixed(2);
                    values.push(parseFloat(value));
                }
            }
            subscribeData.push(result);
            if (newsPublishBox == null) {
                newsPublishBox = dialog.showNotification({
                    title: "新闻订阅发布",
                    content: result.message,
                    bars: values,
                    type: "info"
                });
            } else {
                dialog.setNotificationContent(newsPublishBox, result.message);
                dialog.setNotificationProgress(newsPublishBox, values);
            }

            switch (result.type) {
                case 0:
                    outPutSuccess(result.message);
                    break;
                case 1:
                    outPutInfo(result.message);
                    break;
                case 2:
                    outPutError(result.message);
                    break;
                case 3:
                    outPutSuccess(result.message);
                    setTimeout(function () {
                        dialog.closeNotification(newsPublishBox);
                        newsPublishBox = null;
                    }, 1000);
                    console.log(subscribeData);
                    break;
            }
        });

        // 就绪通知
        connection.on("ready", function (result) {
            console.info(result);
        });

        // 系统通知
        connection.on("systemNotification", function (msg) {
            dialog.toast(msg, 'info');
        });

        // 站点地图生成进度通知
        connection.on("siteMapPushMessage", function (data) {
            // MessageLevel: 0=Info, 1=Warning, 2=Error
            const typeMap = ['success', 'warning', 'error'];
            const type = typeMap[data.level] || 'info';
            
            // 格式化时间
            const time = new Date(data.timestamp).toLocaleTimeString('zh-CN', {
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });
            
            // 在右上角显示 toast(移动端会自动适配到底部)
            dialog.toast(`[${time}] ${data.message}`, type, 4000, 'top-right');
            
            // 同时输出到控制台
            if (type === 'error') {
                outPutError(`[Sitemap] ${data.message}`);
            } else if (type === 'warning') {
                outPutWarning(`[Sitemap] ${data.message}`);
            } else {
                outPutInfo(`[Sitemap] ${data.message}`);
            }
        });

        return connection;
    } catch (error) {
        console.error('SignalR 主通知连接失败:', error);
        updateConnectionStatus('disconnected');
        return null;
    }
}

/**
 * 初始化应用通知连接
 */
async function initAppNotification() {
    try {
        const appConnection = new signalR
            .HubConnectionBuilder()
            .withUrl("/app/notification", {
                skipNegotiation: true,
                transport: signalR.HttpTransportType.WebSockets,
            })
            .withAutomaticReconnect()
            .build();

        await appConnection.start();

        appConnection.on("systemMessage", function (level, message) {
            if (level === 0) {
                // 成功
                outPutSuccess(message);
                dialog.toast(message, 'success');
            } else if (level === 1) {
                // 警告
                outPutWarning(message);
                dialog.toast(message, 'warning');
            } else if (level === 2) {
                // 错误
                outPutError(message);
                dialog.toast(message, 'error');
            }
        });

        return appConnection;
    } catch (error) {
        console.error('SignalR 应用通知连接失败:', error);
        return null;
    }
}

/**
 * 请求浏览器原生通知权限并显示通知
 * @param {Object} option - 通知选项
 * @param {string} option.title - 通知标题
 * @param {string} option.content - 通知内容
 * @param {string} [option.image] - 通知图标
 * @param {string} [option.tag] - 通知标签
 * @returns {Promise<Notification|null>}
 */
async function requestBrowserNotification(option) {
    if (!("Notification" in window)) {
        return null;
    }

    const permission = await Notification.requestPermission();

    const setting = {
        title: "",
        content: "",
        image: "https://cdn.dpangzi.com/logo.png",
        ...option
    };

    if (permission === "granted") {
        return new Notification(setting.title, {
            icon: setting.image,
            body: setting.content,
            lang: "zh-cn",
            tag: setting.tag
        });
    }

    return null;
}

/**
 * 初始化所有 SignalR 连接
 */
export async function initSystemNotifications() {
    // 阻止状态图标的点击冒泡,避免触发彩蛋
    const statusElement = document.getElementById('signalr-status');
    if (statusElement) {
        statusElement.addEventListener('click', (e) => {
            e.stopPropagation();
        });
    }

    await Promise.all([
        initMainNotification(),
        initAppNotification()
    ]);
}

评论加载中...