// 聊天室居中大卡片通知组件，提供 window.chatBanner.show/close 兼容入口。

const DEFAULT_BANNER_ID = "chat-banner-default";
const BANNER_KEYFRAMES_ID = "appoint-keyframes";

/**
 * 将任意文本转为 HTML 安全文本。
 *
 * @param {unknown} text
 * @returns {string}
 */
function escapeBannerText(text) {
    return String(text ?? "")
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

/**
 * 将多行纯文本转为带换行的安全 HTML。
 *
 * @param {unknown} text
 * @returns {string}
 */
function renderMultilineText(text) {
    return escapeBannerText(text).replace(/\n/g, "<br>");
}

/**
 * 注入 Banner 入场与退场动画，避免重复创建 style 节点。
 *
 * @returns {void}
 */
function ensureBannerKeyframes() {
    if (document.getElementById(BANNER_KEYFRAMES_ID)) {
        return;
    }

    const style = document.createElement("style");
    style.id = BANNER_KEYFRAMES_ID;
    style.textContent = `
        @keyframes appoint-pop {
            0%   { opacity: 0; transform: translate(-50%,-50%) scale(0.5); }
            70%  { transform: translate(-50%,-50%) scale(1.05); }
            100% { opacity: 1; transform: translate(-50%,-50%) scale(1); }
        }
        @keyframes appoint-fade-out {
            from { opacity: 1; }
            to   { opacity: 0; transform: translate(-50%,-50%) scale(0.9); }
        }
    `;
    document.head.appendChild(style);
}

/**
 * 播放大卡片退场动画，并在动画后移除节点。
 *
 * @param {HTMLElement} banner
 * @returns {void}
 */
function closeBannerElement(banner) {
    banner.style.animation = "appoint-fade-out 0.5s ease forwards";
    window.setTimeout(() => banner.remove(), 500);
}

/**
 * 生成大卡片按钮 HTML。
 *
 * @param {Array<object>} buttons
 * @returns {string}
 */
function renderButtons(buttons) {
    if (buttons.length === 0) {
        return "";
    }

    const buttonItems = buttons.map((button, index) => `
        <button data-banner-btn="${index}"
            style="background:${button.color || "#10b981"}; color:#fff; border:none; border-radius:8px;
                   padding:8px 20px; font-size:13px; font-weight:bold; cursor:pointer;
                   box-shadow:0 4px 12px rgba(0,0,0,0.25);">
            ${escapeBannerText(button.label || "确定")}
        </button>
    `).join("");

    return `<div style="margin-top:18px; display:flex; gap:10px; justify-content:center;">${buttonItems}</div>`;
}

/**
 * 创建全局大卡片通知 API。
 *
 * @returns {{show: Function, close: Function}}
 */
function createChatBanner() {
    return {
        /**
         * 显示居中大卡片通知。
         *
         * @param {object} options
         * @param {string} [options.id] 同 ID 会替换旧弹窗
         * @param {string} [options.icon] Emoji 图标
         * @param {string} [options.title] 小标题
         * @param {string} [options.name] 大名字行
         * @param {string} [options.body] 主内容纯文本
         * @param {string} [options.sub] 副内容纯文本
         * @param {string[]} [options.gradient] 渐变颜色
         * @param {string} [options.titleColor] 小标题颜色
         * @param {number} [options.autoClose] 自动关闭毫秒，0 表示不自动关闭
         * @param {Array<{label: string, color?: string, onClick?: Function}>} [options.buttons] 操作按钮
         * @returns {void}
         */
        show(options = {}) {
            ensureBannerKeyframes();
            window.chatSound?.ding?.();

            const id = options.id || DEFAULT_BANNER_ID;
            const gradient = (options.gradient || ["#4f46e5", "#7c3aed", "#db2777"]).join(", ");
            const titleColor = options.titleColor || "#fde68a";
            const autoClose = options.autoClose ?? 5000;
            const buttons = Array.isArray(options.buttons) ? options.buttons : [];
            const hasButtons = buttons.length > 0;

            // 同 ID 弹窗只保留最新一条，避免任命、红包等通知堆叠遮挡。
            document.getElementById(id)?.remove();

            const banner = document.createElement("div");
            banner.id = id;
            banner.style.cssText = `
                position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%);
                z-index: 99999; text-align: center;
                animation: appoint-pop 0.5s cubic-bezier(0.175,0.885,0.32,1.275);
                ${hasButtons ? "pointer-events: auto;" : "pointer-events: none;"}
            `;

            banner.innerHTML = `
                <div style="background: linear-gradient(135deg, ${gradient});
                            border-radius: 20px; padding: 28px 44px;
                            box-shadow: 0 20px 60px rgba(0,0,0,0.4);
                            border: 2px solid rgba(255,255,255,0.25); backdrop-filter: blur(8px);
                            min-width: 260px;">
                    ${options.icon ? `<div style="font-size:40px; margin-bottom:8px;">${escapeBannerText(options.icon)}</div>` : ""}
                    ${options.title ? `<div style="color:${titleColor}; font-size:13px; font-weight:bold; letter-spacing:3px; margin-bottom:12px;">
                        ══ ${escapeBannerText(options.title)} ══
                    </div>` : ""}
                    ${options.name ? `<div style="color:white; font-size:22px; font-weight:900; text-shadow:0 2px 8px rgba(0,0,0,0.3);">
                        ${escapeBannerText(options.name)}
                    </div>` : ""}
                    ${options.body ? `<div style="color:rgba(255,255,255,0.9); font-size:14px; margin-top:10px;">${renderMultilineText(options.body)}</div>` : ""}
                    ${options.sub ? `<div style="color:rgba(255,255,255,0.6); font-size:12px; margin-top:6px;">${renderMultilineText(options.sub)}</div>` : ""}
                    ${renderButtons(buttons)}
                    <div style="color:rgba(255,255,255,0.35); font-size:11px; margin-top:14px;">
                        ${new Date().toLocaleTimeString("zh-CN")}
                    </div>
                </div>
            `;

            document.body.appendChild(banner);

            buttons.forEach((button, index) => {
                const element = banner.querySelector(`[data-banner-btn="${index}"]`);
                if (!element) {
                    return;
                }

                element.addEventListener("click", () => {
                    if (typeof button.onClick === "function") {
                        button.onClick(element, () => closeBannerElement(banner));
                        return;
                    }

                    closeBannerElement(banner);
                });
            });

            if (autoClose > 0) {
                window.setTimeout(() => {
                    if (document.getElementById(id)) {
                        closeBannerElement(banner);
                    }
                }, autoClose);
            }
        },

        /**
         * 关闭指定 ID 的大卡片通知。
         *
         * @param {string} [id]
         * @returns {void}
         */
        close(id) {
            const banner = document.getElementById(id || DEFAULT_BANNER_ID);
            if (!banner) {
                return;
            }

            closeBannerElement(banner);
        },
    };
}

/**
 * 绑定全局大卡片通知 API。
 *
 * @returns {void}
 */
export function bindChatBanner() {
    if (typeof document === "undefined" || window.chatBanner) {
        return;
    }

    window.chatBanner = createChatBanner();
}
