// 礼包红包前端交互模块，负责发包、抢包、弹窗倒计时和广播监听。

let redPacketEnvelopeId = null;
let redPacketExpireAt = null;
let redPacketTotalSeconds = 120;
let redPacketTimer = null;
let redPacketClaimed = false;
let redPacketType = "gold";
let redPacketEventsBound = false;

/**
 * 读取 CSRF Token，给红包接口请求统一使用。
 *
 * @returns {string}
 */
function csrfToken() {
    return document.querySelector('meta[name="csrf-token"]')?.content ?? "";
}

/**
 * 读取指定 DOM 节点。
 *
 * @param {string} id 节点 ID
 * @returns {HTMLElement|null}
 */
function byId(id) {
    return document.getElementById(id);
}

/**
 * 重置礼包按钮状态。
 *
 * @param {HTMLButtonElement|null} button 礼包按钮
 * @returns {void}
 */
function resetRedPacketButton(button) {
    if (!button) {
        return;
    }

    button.disabled = false;
    button.innerHTML = "🧧 礼包";
}

/**
 * 读取当前职务的礼包红包默认配置。
 *
 * @returns {Promise<{amount:number,count:number,expire_seconds:number}>}
 */
async function fetchRedPacketConfig() {
    const response = await fetch("/command/red-packet/config", {
        headers: {
            Accept: "application/json",
            "X-CSRF-TOKEN": csrfToken(),
        },
    });
    const data = await response.json();

    if (!response.ok || data.status !== "success") {
        throw new Error(data.message || "读取礼包配置失败");
    }

    return data;
}

/**
 * 发起实际发包请求。
 *
 * @param {"gold"|"exp"} type 礼包类型
 * @returns {Promise<void>}
 */
async function doSendRedPacket(type) {
    const button = byId("red-packet-btn");

    if (button) {
        button.disabled = true;
        button.textContent = "发送中…";
    }

    try {
        const response = await fetch("/command/red-packet/send", {
            method: "POST",
            headers: {
                "X-CSRF-TOKEN": csrfToken(),
                "Content-Type": "application/json",
                Accept: "application/json",
            },
            body: JSON.stringify({
                room_id: window.chatContext.roomId,
                type,
            }),
        });
        const data = await response.json();

        if (!response.ok || data.status !== "success") {
            await window.chatDialog.alert(data.message || "发送失败", "操作失败", "#cc4444");
        }
    } catch (error) {
        await window.chatDialog.alert(`发送失败：${error.message}`, "操作失败", "#cc4444");
    } finally {
        setTimeout(() => resetRedPacketButton(button), 3000);
    }
}

/**
 * superlevel 点击“礼包”按钮后弹出类型选择。
 *
 * @returns {Promise<void>}
 */
export async function sendRedPacket() {
    const button = byId("red-packet-btn");

    if (button) {
        button.disabled = true;
        button.textContent = "读取中…";
    }

    try {
        const config = await fetchRedPacketConfig();
        const amountText = Number(config.amount || 0).toLocaleString("zh-CN");
        const countText = Number(config.count || 0).toLocaleString("zh-CN");

        window.chatBanner.show({
            icon: "🧧",
            title: "发出礼包",
            name: "选择礼包类型",
            body: `将发出 ${amountText} 数量共 ${countText} 份的礼包，系统凭空发放，房间成员先到先得！`,
            gradient: ["#991b1b", "#dc2626", "#ea580c"],
            titleColor: "#fde68a",
            autoClose: 0,
            buttons: [
                {
                    label: "💰 金币礼包",
                    color: "#d97706",
                    onClick(buttonEl, close) {
                        close();
                        doSendRedPacket("gold");
                    },
                },
                {
                    label: "✨ 经验礼包",
                    color: "#7c3aed",
                    onClick(buttonEl, close) {
                        close();
                        doSendRedPacket("exp");
                    },
                },
                {
                    label: "取消",
                    color: "rgba(255,255,255,0.15)",
                    onClick(buttonEl, close) {
                        close();
                    },
                },
            ],
        });
    } catch (error) {
        await window.chatDialog.alert(error.message || "读取礼包配置失败", "操作失败", "#cc4444");
    } finally {
        resetRedPacketButton(button);
    }
}

/**
 * 从触发按钮读取红包发送时间，兼容历史系统消息中的 data-sent-at。
 *
 * @returns {number|null}
 */
function readSentAtFromCurrentEvent() {
    if (!window.event?.currentTarget?.dataset?.sentAt) {
        return null;
    }

    const sentAt = Number.parseInt(window.event.currentTarget.dataset.sentAt, 10);

    return Number.isNaN(sentAt) ? null : sentAt;
}

/**
 * 预查红包状态，避免已过期或抢完的红包弹窗闪现。
 *
 * @param {number|string} envelopeId 红包 ID
 * @param {number} totalCount 总份数
 * @returns {Promise<{allowed:boolean, remainingCount:number, totalCount:number}>}
 */
async function preflightRedPacketStatus(envelopeId, totalCount) {
    try {
        const response = await fetch(`/red-packet/${envelopeId}/status`, {
            headers: {
                Accept: "application/json",
                "X-CSRF-TOKEN": csrfToken(),
            },
        });
        const data = await response.json();

        if (data.status !== "success") {
            return {
                allowed: true,
                remainingCount: totalCount,
                totalCount,
            };
        }

        if (data.is_expired || data.envelope_status === "expired") {
            window.chatToast?.show({
                title: "⏰ 礼包已过期",
                message: "该红包已过期，无法领取。",
                icon: "⏰",
                color: "#9ca3af",
                duration: 4000,
            });

            return {
                allowed: false,
                remainingCount: 0,
                totalCount,
            };
        }

        if (data.remaining_count <= 0 || data.envelope_status === "completed") {
            window.chatToast?.show({
                title: "😅 手慢了！",
                message: "红包已被抢完，下次要快一点哦！",
                icon: "🧧",
                color: "#f59e0b",
                duration: 4000,
            });

            return {
                allowed: false,
                remainingCount: 0,
                totalCount,
            };
        }

        if (data.has_claimed) {
            window.chatToast?.show({
                title: "✅ 已领取",
                message: "您已成功领取过本次礼包！",
                icon: "🧧",
                color: "#10b981",
                duration: 4000,
            });

            return {
                allowed: false,
                remainingCount: data.remaining_count,
                totalCount: data.total_count || totalCount,
            };
        }

        return {
            allowed: true,
            remainingCount: data.remaining_count,
            totalCount: data.total_count || totalCount,
        };
    } catch (error) {
        console.error("红包状态前置预查失败:", error);

        return {
            allowed: true,
            remainingCount: totalCount,
            totalCount,
        };
    }
}

/**
 * 应用红包弹窗的类型配色。
 *
 * @param {"gold"|"exp"} type 礼包类型
 * @returns {{typeIcon:string,typeName:string}}
 */
function applyRedPacketTypeStyle(type) {
    const isExp = type === "exp";
    const typeIcon = isExp ? "✨" : "💰";
    const typeName = isExp ? "经验" : "金币";
    const headerBackground = isExp
        ? "linear-gradient(160deg,#6d28d9 0%,#5b21b6 50%,#4c1d95 100%)"
        : "linear-gradient(160deg,#dc2626 0%,#b91c1c 50%,#991b1b 100%)";
    const claimBackground = isExp
        ? "linear-gradient(135deg,#7c3aed,#4f46e5)"
        : "linear-gradient(135deg,#dc2626,#ea580c)";

    byId("rp-header").style.background = headerBackground;

    const claimButton = byId("rp-claim-btn");
    if (claimButton) {
        claimButton.style.background = claimBackground;
    }

    return {
        typeIcon,
        typeName,
    };
}

/**
 * 填充红包弹窗内容。
 *
 * @param {Record<string, any>} payload 弹窗数据
 * @returns {void}
 */
function renderRedPacketModal(payload) {
    const modal = byId("red-packet-modal");
    const claimButton = byId("rp-claim-btn");
    const styleConfig = applyRedPacketTypeStyle(payload.type);

    modal.style.setProperty("display", "flex", "important");
    modal.style.setProperty("z-index", "9999999", "important");
    modal.style.setProperty("opacity", "1", "important");
    modal.style.setProperty("visibility", "visible", "important");

    byId("rp-sender-name").textContent = `${payload.senderUsername} 的礼包`;
    byId("rp-total-amount").textContent = payload.totalAmount;
    byId("rp-total-count").textContent = payload.totalCount;
    byId("rp-remaining").textContent = payload.remainingCount;
    byId("rp-countdown").textContent = payload.expireSeconds;
    byId("rp-timer-bar").style.width = "100%";
    byId("rp-status-msg").textContent = "";
    byId("rp-claims-list").style.display = "none";
    byId("rp-claims-items").textContent = "";

    const emoji = modal.querySelector(".rp-emoji");
    if (emoji) {
        emoji.textContent = styleConfig.typeIcon;
    }

    const title = modal.querySelector(".rp-title");
    if (title) {
        title.textContent = `${styleConfig.typeName}礼包`;
    }

    const typeLabel = byId("rp-type-label");
    if (typeLabel) {
        typeLabel.textContent = ` ${styleConfig.typeName}`;
    }

    if (claimButton) {
        claimButton.disabled = false;
        claimButton.textContent = `${styleConfig.typeIcon} 立即抢包`;
    }
}

/**
 * 启动红包倒计时。
 *
 * @returns {void}
 */
function startRedPacketTimer() {
    clearInterval(redPacketTimer);
    redPacketTimer = setInterval(() => {
        const remaining = Math.max(0, Math.ceil((redPacketExpireAt - Date.now()) / 1000));
        byId("rp-countdown").textContent = remaining;
        byId("rp-timer-bar").style.width = `${(remaining / redPacketTotalSeconds) * 100}%`;

        if (remaining <= 0) {
            clearInterval(redPacketTimer);

            const claimButton = byId("rp-claim-btn");
            claimButton.disabled = true;
            claimButton.textContent = "礼包已过期";

            const status = byId("rp-status-msg");
            status.style.color = "#9ca3af";
            status.textContent = "红包已过期，即将关闭…";

            setTimeout(() => closeRedPacketModal(), 3000);
        }
    }, 1000);
}

/**
 * 展示红包弹窗，并启动倒计时。
 *
 * @param {number|string} envelopeId 红包 ID
 * @param {string} senderUsername 发包人
 * @param {number|string} totalAmount 总数量
 * @param {number} totalCount 总份数
 * @param {number} expireSeconds 有效秒数
 * @param {"gold"|"exp"} type 礼包类型
 * @returns {Promise<void>}
 */
export async function showRedPacketModal(envelopeId, senderUsername, totalAmount, totalCount, expireSeconds, type = "gold") {
    try {
        const sentAt = readSentAtFromCurrentEvent();
        let calculatedExpireAt = Date.now() + expireSeconds * 1000;

        if (sentAt && sentAt > 0) {
            calculatedExpireAt = (sentAt + expireSeconds) * 1000;
        }

        if (sentAt && Date.now() >= calculatedExpireAt) {
            window.chatToast?.show({
                title: "⏰ 礼包已过期",
                message: "该红包已过期，无法领取。",
                icon: "⏰",
                color: "#9ca3af",
                duration: 4000,
            });
            return;
        }

        const preflight = await preflightRedPacketStatus(envelopeId, totalCount);
        if (!preflight.allowed) {
            return;
        }

        redPacketEnvelopeId = envelopeId;
        redPacketClaimed = false;
        redPacketType = type || "gold";
        redPacketExpireAt = calculatedExpireAt;
        redPacketTotalSeconds = expireSeconds;

        const modal = byId("red-packet-modal");
        if (!modal) {
            window.chatDialog?.alert("致命错误：红包视图容器 #red-packet-modal 找不到！", "系统错误", "#cc4444");
            return;
        }

        renderRedPacketModal({
            senderUsername,
            totalAmount,
            totalCount: preflight.totalCount,
            remainingCount: preflight.remainingCount,
            expireSeconds,
            type: redPacketType,
        });
        startRedPacketTimer();
    } catch (error) {
        console.error("showRedPacketModal 执行失败:", error);
        window.chatDialog?.alert(`红包弹窗初始化异常: ${error.message}`, "系统错误", "#cc4444");
    }
}

/**
 * 关闭红包弹窗并停止倒计时。
 *
 * @returns {void}
 */
export function closeRedPacketModal() {
    const modal = byId("red-packet-modal");

    if (modal) {
        modal.style.display = "none";
    }

    if (redPacketTimer) {
        clearInterval(redPacketTimer);
    }
}

/**
 * 用户点击“立即抢红包”。
 *
 * @returns {Promise<void>}
 */
export async function claimRedPacket() {
    if (!redPacketEnvelopeId) {
        return;
    }

    const button = byId("rp-claim-btn");
    button.disabled = true;
    button.textContent = "抢包中…";

    try {
        const response = await fetch(`/red-packet/${redPacketEnvelopeId}/claim`, {
            method: "POST",
            headers: {
                "X-CSRF-TOKEN": csrfToken(),
                "Content-Type": "application/json",
                Accept: "application/json",
            },
            body: JSON.stringify({
                room_id: window.chatContext.roomId,
            }),
        });
        const data = await response.json();
        handleClaimResponse(response, data, button);
    } catch (error) {
        const status = byId("rp-status-msg");
        status.textContent = "网络异常，请重试";
        status.style.color = "#dc2626";
        button.disabled = false;
        button.textContent = "🧧 立即抢红包";
    }
}

/**
 * 处理抢红包接口响应。
 *
 * @param {Response} response Fetch 响应对象
 * @param {Record<string, any>} data 接口数据
 * @param {HTMLButtonElement} button 抢包按钮
 * @returns {void}
 */
function handleClaimResponse(response, data, button) {
    const status = byId("rp-status-msg");
    const typeLabel = redPacketType === "exp" ? "经验" : "金币";

    if (response.ok && data.status === "success") {
        redPacketClaimed = true;
        button.textContent = "🎉 已抢到！";
        status.style.color = "#16a34a";
        status.textContent = `恭喜！您抢到了 ${data.amount} ${typeLabel}！`;

        const remaining = byId("rp-remaining");
        if (remaining && typeof data.remaining_count === "number") {
            remaining.textContent = data.remaining_count;
        }

        window.chatToast.show({
            title: "🧧 礼包到账",
            message: `恭喜您抢到了礼包 ${data.amount} ${typeLabel}！`,
            icon: "🧧",
            color: redPacketType === "exp" ? "#7c3aed" : "#dc2626",
            duration: 8000,
        });

        setTimeout(() => closeRedPacketModal(), 3000);
        return;
    }

    status.style.color = "#dc2626";
    status.textContent = data.message || "抢包失败";
    updateClaimButtonAfterFailure(button, data.message || "");
}

/**
 * 根据失败原因更新抢包按钮状态。
 *
 * @param {HTMLButtonElement} button 抢包按钮
 * @param {string} message 失败文案
 * @returns {void}
 */
function updateClaimButtonAfterFailure(button, message) {
    const shouldAutoClose = message.includes("已过期")
        || message.includes("已被抢完")
        || message.includes("已抢完")
        || message.includes("红包已抢完或已过期");

    if (shouldAutoClose) {
        button.textContent = "礼包已结束";
        setTimeout(() => closeRedPacketModal(), 3000);
        return;
    }

    if (message.includes("已经领过")) {
        button.textContent = "已参与";
        return;
    }

    button.disabled = false;
    button.textContent = "🧧 立即抢红包";
}

/**
 * 收到领取广播后，同步弹窗内领取名单与剩余数。
 *
 * @param {string} username 领取者用户名
 * @param {number|string} amount 领取数量
 * @param {number} remaining 剩余份数
 * @param {"gold"|"exp"} type 礼包类型
 * @returns {void}
 */
export function updateRedPacketClaimsUI(username, amount, remaining, type = redPacketType) {
    const remainingElement = byId("rp-remaining");
    if (remainingElement) {
        remainingElement.textContent = remaining;
    }

    const list = byId("rp-claims-list");
    const items = byId("rp-claims-items");
    if (!list || !items) {
        return;
    }

    list.style.display = "block";

    const item = document.createElement("div");
    const name = document.createElement("span");
    const value = document.createElement("span");
    const typeLabel = type === "exp" ? "经验" : "金币";

    item.className = "rp-claim-item";
    name.textContent = username;
    value.textContent = `+${amount} ${typeLabel}`;
    item.append(name, value);
    items.prepend(item);

    if (remaining <= 0) {
        const button = byId("rp-claim-btn");
        if (button && !redPacketClaimed) {
            button.disabled = true;
            button.textContent = "礼包已被抢完！";
        }

        clearInterval(redPacketTimer);
        setTimeout(() => closeRedPacketModal(), 3000);
    }
}

/**
 * 注册红包 Echo 监听。
 *
 * @returns {void}
 */
function setupRedPacketListener() {
    if (!window.Echo || !window.chatContext) {
        setTimeout(setupRedPacketListener, 500);
        return;
    }

    window.Echo.join(`room.${window.chatContext.roomId}`)
        .listen(".red-packet.sent", (event) => {
            showRedPacketModal(
                event.envelope_id,
                event.sender_username,
                event.total_amount,
                event.total_count,
                event.expire_seconds,
                event.type || "gold",
            );
        })
        .listen(".red-packet.claimed", (event) => {
            if (Number(event.envelope_id) !== Number(redPacketEnvelopeId)) {
                return;
            }

            updateRedPacketClaimsUI(
                event.claimer_username,
                event.amount,
                event.remaining_count,
                event.type || redPacketType,
            );
        });
}

/**
 * 挂载红包全局入口并绑定静态按钮事件。
 *
 * @returns {void}
 */
export function bindRedPacketPanelControls() {
    if (typeof window === "undefined" || typeof document === "undefined") {
        return;
    }

    window.sendRedPacket = sendRedPacket;
    window.showRedPacketModal = showRedPacketModal;
    window.closeRedPacketModal = closeRedPacketModal;
    window.claimRedPacket = claimRedPacket;
    window.updateRedPacketClaimsUI = updateRedPacketClaimsUI;

    if (redPacketEventsBound) {
        return;
    }

    redPacketEventsBound = true;

    byId("red-packet-modal")?.addEventListener("click", (event) => {
        if (event.target === event.currentTarget) {
            closeRedPacketModal();
        }
    });

    byId("rp-close-btn")?.addEventListener("click", (event) => {
        event.preventDefault();
        closeRedPacketModal();
    });

    byId("rp-claim-btn")?.addEventListener("click", (event) => {
        event.preventDefault();
        claimRedPacket();
    });

    document.addEventListener("DOMContentLoaded", setupRedPacketListener);
}
