import "./bootstrap";
import "./chat-room.js";

// 这个文件负责处理浏览器与 Laravel Reverb WebSocket 服务器的通信。
// 通过 Presence Channel 实现聊天室的核心监听。

function isHolidayObject(value) {
    return value !== null && typeof value === "object" && !Array.isArray(value);
}

function firstHolidayDefined(...values) {
    for (const value of values) {
        if (value !== undefined && value !== null && value !== "") {
            return value;
        }
    }

    return null;
}

function pickHolidayObject(...values) {
    for (const value of values) {
        if (isHolidayObject(value)) {
            return value;
        }
    }

    return {};
}

function mergeHolidayObjects(...values) {
    return Object.assign({}, ...values.filter(isHolidayObject));
}

function toHolidayNumber(value, fallback = null) {
    if (value === undefined || value === null || value === "") {
        return fallback;
    }

    const parsedValue = Number(value);

    return Number.isFinite(parsedValue) ? parsedValue : fallback;
}

export function normalizeHolidayBroadcastEvent(payload = {}) {
    const runPayload = pickHolidayObject(payload.run, payload.holiday_run);
    const snapshotPayload = pickHolidayObject(
        payload.snapshot,
        payload.run_snapshot,
        payload.batch_snapshot,
        runPayload.snapshot,
        runPayload.batch_snapshot,
    );
    const eventPayload = pickHolidayObject(
        payload.event,
        payload.holiday_event,
        runPayload.event,
        runPayload.template,
        snapshotPayload.event,
        snapshotPayload.template,
    );
    const mergedPayload = mergeHolidayObjects(
        eventPayload,
        payload,
        runPayload,
        snapshotPayload,
    );
    const fixedAmount = toHolidayNumber(
        firstHolidayDefined(
            snapshotPayload.fixed_amount,
            runPayload.fixed_amount,
            payload.fixed_amount,
        ),
    );

    return {
        ...payload,
        ...mergedPayload,
        run_id: firstHolidayDefined(
            payload.run_id,
            runPayload.run_id,
            runPayload.id,
            snapshotPayload.run_id,
        ),
        event_id: firstHolidayDefined(
            payload.event_id,
            runPayload.event_id,
            snapshotPayload.event_id,
            eventPayload.id,
        ),
        name: firstHolidayDefined(
            snapshotPayload.name,
            runPayload.name,
            payload.name,
            eventPayload.name,
            "节日福利",
        ),
        description: firstHolidayDefined(
            snapshotPayload.description,
            runPayload.description,
            payload.description,
            eventPayload.description,
            "",
        ),
        total_amount:
            toHolidayNumber(
                firstHolidayDefined(
                    snapshotPayload.total_amount,
                    runPayload.total_amount,
                    payload.total_amount,
                ),
                0,
            ) ?? 0,
        max_claimants:
            toHolidayNumber(
                firstHolidayDefined(
                    snapshotPayload.max_claimants,
                    runPayload.max_claimants,
                    payload.max_claimants,
                ),
                0,
            ) ?? 0,
        distribute_type: firstHolidayDefined(
            snapshotPayload.distribute_type,
            runPayload.distribute_type,
            payload.distribute_type,
            fixedAmount !== null ? "fixed" : "random",
        ),
        fixed_amount: fixedAmount,
        scheduled_for: firstHolidayDefined(
            snapshotPayload.scheduled_for,
            runPayload.scheduled_for,
            payload.scheduled_for,
            snapshotPayload.send_at,
            runPayload.send_at,
            payload.send_at,
        ),
        expires_at: firstHolidayDefined(
            snapshotPayload.expires_at,
            runPayload.expires_at,
            payload.expires_at,
            snapshotPayload.claim_deadline_at,
            runPayload.claim_deadline_at,
            payload.claim_deadline_at,
        ),
        repeat_type: firstHolidayDefined(
            snapshotPayload.repeat_type,
            runPayload.repeat_type,
            payload.repeat_type,
            eventPayload.repeat_type,
        ),
        round_no: firstHolidayDefined(
            snapshotPayload.round_no,
            runPayload.round_no,
            payload.round_no,
            snapshotPayload.sequence,
            runPayload.sequence,
            payload.sequence,
            snapshotPayload.issue_no,
            runPayload.issue_no,
            payload.issue_no,
        ),
        round_label: firstHolidayDefined(
            snapshotPayload.round_label,
            runPayload.round_label,
            payload.round_label,
            snapshotPayload.batch_label,
            runPayload.batch_label,
            payload.batch_label,
        ),
        snapshot: mergeHolidayObjects(eventPayload, runPayload, snapshotPayload),
    };
}

window.normalizeHolidayBroadcastEvent = normalizeHolidayBroadcastEvent;

export function initChat(roomId) {
    if (!roomId) {
        console.error("未提供 roomId，无法初始化 WebSocket 连接。");
        return;
    }

    const userId = window.chatContext?.userId;

    // 监听全局系统事件（如 AI 机器人开关）
    window.Echo.channel('chat.system')
        .listen('ChatBotToggled', (e) => {
            console.log("机器人开关:", e);
            window.dispatchEvent(new CustomEvent("chat:bot-toggled", { detail: e }));
        });

    // 加入带有登录人员追踪的 Presence Channel
    window.Echo.join(`room.${roomId}`)
        // 当自己成功连接时，获取当前在这里的所有人列表
        .here((users) => {
            console.log("当前房间内的在线人员:", users);
            // 触发自定义事件，让具体的前端 UI 去接管渲染
            window.dispatchEvent(
                new CustomEvent("chat:here", { detail: users }),
            );
        })
        // 监听其他人的加入
        .joining((user) => {
            console.log(user.username + " 进入了房间");
            window.dispatchEvent(
                new CustomEvent("chat:joining", { detail: user }),
            );
        })
        // 监听其他人的离开
        .leaving((user) => {
            console.log(user.username + " 离开了房间");
            window.dispatchEvent(
                new CustomEvent("chat:leaving", { detail: user }),
            );
        })
        // 监听新发送的文本消息
        .listen("MessageSent", (e) => {
            console.log("收到新发言:", e.message);
            window.dispatchEvent(
                new CustomEvent("chat:message", { detail: e.message }),
            );
        })
        // 监听踢出事件（通常判断是不是自己被踢出了）
        .listen("UserKicked", (e) => {
            console.log("踢出通知:", e);
            window.dispatchEvent(new CustomEvent("chat:kicked", { detail: e }));
        })
        // 监听封口禁言事件
        .listen("UserMuted", (e) => {
            console.log("禁言通知:", e);
            window.dispatchEvent(new CustomEvent("chat:muted", { detail: e }));
        })
        // 监听房间主题被改变
        .listen("RoomTitleUpdated", (e) => {
            console.log("主题改变:", e);
            window.dispatchEvent(
                new CustomEvent("chat:title-updated", { detail: e }),
            );
        })
        // 监听管理员全员清屏
        .listen("ScreenCleared", (e) => {
            console.log("全员清屏:", e);
            window.dispatchEvent(
                new CustomEvent("chat:screen-cleared", { detail: e }),
            );
        })
        // 监听用户状态变更，实时刷新右侧在线名单。
        .listen("UserStatusUpdated", (e) => {
            console.log("用户状态更新:", e);
            window.dispatchEvent(
                new CustomEvent("chat:user-status-updated", { detail: e }),
            );
        })
        // 监听站长触发的全员刷新
        .listen("BrowserRefreshRequested", (e) => {
            console.log("全员刷新:", e);
            window.dispatchEvent(
                new CustomEvent("chat:browser-refresh-requested", { detail: e }),
            );
        })
        // 监听管理员触发的全屏特效（烟花/下雨/雷电）
        .listen("EffectBroadcast", (e) => {
            console.log("特效播放:", e);
            window.dispatchEvent(new CustomEvent("chat:effect", { detail: e }));
        })
        // 监听任命公告（礼花 + 隆重弹窗）
        .listen("AppointmentAnnounced", (e) => {
            console.log("任命公告:", e);
            window.dispatchEvent(
                new CustomEvent("chat:appointment-announced", { detail: e }),
            );
        })
        // ─── 婚姻系统：全局事件（广播给整个房间） ────────────────
        .listen(".marriage.accepted", (e) => {
            console.log("结婚公告:", e);
            window.dispatchEvent(
                new CustomEvent("chat:marriage-accepted", { detail: e }),
            );
        })
        .listen(".marriage.divorced", (e) => {
            console.log("离婚公告:", e);
            window.dispatchEvent(
                new CustomEvent("chat:marriage-divorced", { detail: e }),
            );
        })
        .listen(".wedding.celebration", (e) => {
            console.log("婚礼庆典:", e);
            window.dispatchEvent(
                new CustomEvent("chat:wedding-celebration", { detail: e }),
            );
        })
        // ─── 节日福利：系统定时发放 ────────────────────────────────
        .listen(".holiday.started", (e) => {
            const holidayPayload = normalizeHolidayBroadcastEvent(e);
            console.log("节日福利批次开始:", holidayPayload);
            window.dispatchEvent(
                new CustomEvent("chat:holiday.started", { detail: holidayPayload }),
            );
        })
        // ─── 百家乐：开局 & 结算 ──────────────────────────────────
        .listen(".baccarat.opened", (e) => {
            console.log("百家乐开局:", e);
            window.dispatchEvent(
                new CustomEvent("chat:baccarat.opened", { detail: e }),
            );
        })
        .listen(".baccarat.pool_updated", (e) => {
            console.log("百家乐押注更新:", e);
            window.dispatchEvent(
                new CustomEvent("chat:baccarat.pool_updated", { detail: e }),
            );
        })
        .listen(".baccarat.settled", (e) => {
            console.log("百家乐结算:", e);
            window.dispatchEvent(
                new CustomEvent("chat:baccarat.settled", { detail: e }),
            );
        })
        // ─── 赛马：开场 / 进度 / 结算 ────────────────────────────────
        .listen(".horse.opened", (e) => {
            console.log("赛马开场:", e);
            window.dispatchEvent(
                new CustomEvent("chat:horse.opened", { detail: e }),
            );
        })
        .listen(".horse.progress", (e) => {
            console.log("赛马进度:", e);
            window.dispatchEvent(
                new CustomEvent("chat:horse.progress", { detail: e }),
            );
        })
        .listen(".horse.settled", (e) => {
            console.log("赛马结算:", e);
            window.dispatchEvent(
                new CustomEvent("chat:horse.settled", { detail: e }),
            );
        });

    // 监听当前用户私有消息，确保悄悄话与定向系统通知不会泄漏给整个房间。
    if (userId) {
        window.Echo.private(`user.${userId}`)
            .listen("MessageSent", (e) => {
                console.log("收到私有聊天消息:", e.message);
                window.dispatchEvent(
                    new CustomEvent("chat:message", { detail: e.message }),
                );
            })
            .listen("UserBrowserRefreshRequested", (e) => {
                console.log("收到定向刷新通知:", e);
                window.dispatchEvent(
                    new CustomEvent("chat:user-browser-refresh-requested", { detail: e }),
                );
            });
    }
}

/**
 * 初始化婚姻私人频道监听（求婚通知 / 拒绝通知 / 红包领取通知）
 * 在用户登录成功后调用，监听 user.{id} 私人频道的婚姻事件。
 *
 * @param {number} userId 当前登录用户 ID
 */
export function initMarriagePrivateChannel(userId) {
    if (!userId || !window.Echo) return;

    window.Echo.private(`user.${userId}`)
        // 收到求婚通知（目标方）
        .listen(".marriage.proposed", (e) => {
            console.log("收到求婚:", e);
            window.dispatchEvent(
                new CustomEvent("chat:marriage-proposed", { detail: e }),
            );
        })
        // 求婚被拒绝（发起方）
        .listen(".marriage.rejected", (e) => {
            console.log("求婚被拒:", e);
            window.dispatchEvent(
                new CustomEvent("chat:marriage-rejected", { detail: e }),
            );
        })
        // 求婚过期（发起方）
        .listen(".marriage.expired", (e) => {
            console.log("求婚超时:", e);
            window.dispatchEvent(
                new CustomEvent("chat:marriage-expired", { detail: e }),
            );
        })
        // 协议离婚申请通知（对方）
        .listen(".marriage.divorce-requested", (e) => {
            console.log("离婚申请:", e);
            window.dispatchEvent(
                new CustomEvent("chat:divorce-requested", { detail: e }),
            );
        })
        // 红包领取成功通知
        .listen(".envelope.claimed", (e) => {
            console.log("红包到账:", e);
            window.dispatchEvent(
                new CustomEvent("chat:envelope-claimed", { detail: e }),
            );
        });
}

// 供全局调用
window.initChat = initChat;
window.initMarriagePrivateChannel = initMarriagePrivateChannel;
