/**
 * 聊天室心跳与存点模块：定时存点、手动存点、退出房间、掉线检测。
 * 从 Blade 内联脚本 scripts.blade.php 迁移至 Vite 模块。
 */

import { escapeHtml } from "./html.js";
import { pruneMessageContainer } from "./message-renderer.js";

const MAX_HEARTBEAT_FAILS = 3;
const HEARTBEAT_INTERVAL = 60 * 1000;

let heartbeatInterval = null;
let heartbeatFailCount = 0;
let leaveRequestInFlight = false;

/**
 * 获取 CSRF Token。
 *
 * @returns {string}
 */
function csrf() {
    return document.querySelector('meta[name="csrf-token"]')?.content ?? "";
}

/**
 * 获取共享状态对象。
 *
 * @returns {Object|null}
 */
function getState() {
    return window.chatState;
}

// ── 存点功能（手动 + 自动）─────────────────────

/**
 * 执行一次存点请求，向服务端同步在线状态并获取经验/金币。
 *
 * @param {boolean} silent 静默模式（true=仅心跳，不显示存点提示）
 * @returns {Promise<void>}
 */
async function saveExp(silent = false) {
    if (!window.chatContext?.heartbeatUrl) return;

    const state = getState();

    try {
        const response = await fetch(window.chatContext.heartbeatUrl, {
            method: "POST",
            headers: {
                "X-CSRF-TOKEN": csrf(),
                "Accept": "application/json",
            },
        });

        // 检测登录态失效
        if (response.status === 401 || response.status === 419) {
            await notifyExpiredLeave();
            window.chatDialog?.alert(
                "⚠️ 您的登录已失效（可能超时或在其他设备登录），请重新登录。",
                "连接警告",
                "#b45309"
            );
            window.location.href = "/";
            return;
        }

        const data = await response.json();
        if (response.ok && data.status === "success") {
            heartbeatFailCount = 0;

            const now = new Date();
            const timeStr = now.getHours().toString().padStart(2, "0") + ":" +
                now.getMinutes().toString().padStart(2, "0") + ":" +
                now.getSeconds().toString().padStart(2, "0");
            const d = data.data;
            const identitySummary = d.identity_summary ? `${d.identity_summary} · ` : "";

            let levelInfo = "";
            if (d.is_max_level) {
                levelInfo = `⏰ 手动存点 · ${identitySummary}LV.${d.user_level} · 经验 ${d.exp_num} · 金币 ${d.jjb} · 已满级 ✓`;
            } else {
                levelInfo = `⏰ 手动存点 · ${identitySummary}LV.${d.user_level} · 经验 ${d.exp_num} · 金币 ${d.jjb}`;
            }

            // 本次获得的奖励提示
            let gainInfo = "";
            if (d.exp_gain > 0 || d.jjb_gain > 0) {
                const parts = [];
                if (d.exp_gain > 0) parts.push(`经验+${d.exp_gain}`);
                if (d.jjb_gain > 0) parts.push(`金币+${d.jjb_gain}`);
                gainInfo = ` 本次获得：${parts.join("，")}`;
            }

            // 升级通知
            if (data.data.leveled_up) {
                const upDiv = document.createElement("div");
                upDiv.className = "msg-line";
                upDiv.innerHTML = `<span style="color: #d97706; font-weight: bold;">【系统】恭喜！你的经验值已达 ${d.exp_num}，等级突破至 LV.${d.user_level}！🌟</span><span class="msg-time">(${timeStr})</span>`;
                const container2 = state?.container2;
                if (container2) {
                    container2.appendChild(upDiv);
                    if (state?.autoScroll) container2.scrollTop = container2.scrollHeight;
                }
            }

            // 存点消息输出到包厢窗口
            if (!silent) {
                const container2 = state?.container2 || document.getElementById("chat-messages-container2");
                if (container2) {
                    const detailDiv = document.createElement("div");
                    detailDiv.className = "msg-line";
                    detailDiv.dataset.autosave = "1";
                    detailDiv.innerHTML = `<span style="color: green;">${escapeHtml(levelInfo + gainInfo)}</span><span class="msg-time">(${timeStr})</span>`;

                    // 手动存点和自动存点共用同一条界面占位，避免包厢窗口堆积旧存点通知
                    if (state) {
                        state.lastAutosaveNode?.remove();
                        state.lastAutosaveNode = detailDiv;
                    }
                    container2.appendChild(detailDiv);
                    pruneMessageContainer(container2, window.chatState?.PRIVATE_MESSAGE_NODE_LIMIT || 300);
                    if (state?.autoScroll) container2.scrollTop = container2.scrollHeight;
                }
            }
        }
    } catch (e) {
        console.error("存点失败", e);
        heartbeatFailCount++;

        if (heartbeatFailCount >= MAX_HEARTBEAT_FAILS) {
            window.chatDialog?.alert(
                "⚠️ 与服务器的连接已断开，请检查网络后重新登录。",
                "连接警告",
                "#b45309"
            );
            window.location.href = "/";
            return;
        }

        if (!silent) {
            const container2 = state?.container2 || document.getElementById("chat-messages-container2");
            if (container2) {
                const sysDiv = document.createElement("div");
                sysDiv.className = "msg-line";
                sysDiv.innerHTML = '<span style="color: red;">【系统】存点失败，请稍后重试</span>';
                container2.appendChild(sysDiv);
            }
        }
    }
}

// ── 退出房间 ──

/**
 * 主动退出房间并关闭页面。
 *
 * @returns {Promise<void>}
 */
async function leaveRoom() {
    if (leaveRequestInFlight) return;
    leaveRequestInFlight = true;

    try {
        await fetch(window.chatContext.leaveUrl + "?explicit=1", {
            method: "POST",
            headers: {
                "X-CSRF-TOKEN": csrf(),
                "Accept": "application/json",
            },
        });
    } catch (e) {
        console.error(e);
    }

    // 弹出窗口直接关闭，如果不是弹出窗口则跳回首页
    window.close();
    setTimeout(() => {
        window.location.href = "/";
    }, 500);
}

/**
 * 通知服务端登录已过期（用于 401/419 响应时）。
 *
 * @returns {Promise<void>}
 */
async function notifyExpiredLeave() {
    if (leaveRequestInFlight) return;
    leaveRequestInFlight = true;

    try {
        if (!window.chatContext?.expiredLeaveUrl) return;

        await fetch(window.chatContext.expiredLeaveUrl, {
            method: "GET",
            headers: { "Accept": "application/json" },
            credentials: "same-origin",
        });
    } catch (e) {
        console.error(e);
    }
}

// ── 定时器管理 ──

/**
 * 启动心跳定时器（每 60 秒自动存点）。
 */
export function startHeartbeat() {
    stopHeartbeat(); // 防止重复启动

    // 首次心跳延迟 10 秒，让 WebSocket 先连接
    const initialTimer = window.setTimeout(() => saveExp(true), 10000);
    const intervalTimer = window.setInterval(() => saveExp(true), HEARTBEAT_INTERVAL);

    heartbeatInterval = { initial: initialTimer, interval: intervalTimer };
}

/**
 * 停止心跳定时器。
 */
export function stopHeartbeat() {
    if (heartbeatInterval) {
        window.clearTimeout(heartbeatInterval.initial);
        window.clearInterval(heartbeatInterval.interval);
        heartbeatInterval = null;
    }
}

// ── 挂载到 window ──
window.saveExp = saveExp;
window.leaveRoom = leaveRoom;
window.notifyExpiredLeave = notifyExpiredLeave;
window.startHeartbeat = startHeartbeat;
window.stopHeartbeat = stopHeartbeat;

export { saveExp, leaveRoom, notifyExpiredLeave, HEARTBEAT_INTERVAL, MAX_HEARTBEAT_FAILS };
