// 聊天室赚钱面板，注册 earnPanelData Alpine 组件并集中管理 FluidPlayer 加载。

const FLUID_PLAYER_SCRIPT_URL = "https://cdn.fluidplayer.com/v3/current/fluidplayer.min.js";
const FALLBACK_VIDEO_SOURCE = "https://cdn.fluidplayer.com/videos/valerian-1080p.mkv";
const VAST_TAG_URL = "https://s.magsrv.com/v1/vast.php?idzone=5889208";

let earnPanelControlsBound = false;
let earnPanelRegistered = false;
let fluidPlayerScriptPromise = null;

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

/**
 * 显示统一 Toast，避免面板代码直接依赖未初始化对象。
 *
 * @param {object} options
 * @returns {void}
 */
function showToast(options) {
    window.chatToast?.show?.(options);
}

/**
 * 按需加载 FluidPlayer CDN 脚本。
 *
 * @returns {Promise<void>}
 */
function loadFluidPlayerScript() {
    if (typeof window.fluidPlayer === "function") {
        return Promise.resolve();
    }

    if (fluidPlayerScriptPromise) {
        return fluidPlayerScriptPromise;
    }

    fluidPlayerScriptPromise = new Promise((resolve, reject) => {
        const existingScript = document.querySelector(`script[src="${FLUID_PLAYER_SCRIPT_URL}"]`);
        if (existingScript) {
            existingScript.addEventListener("load", () => resolve(), { once: true });
            existingScript.addEventListener("error", () => reject(new Error("FluidPlayer 加载失败")), { once: true });
            return;
        }

        const script = document.createElement("script");
        script.src = FLUID_PLAYER_SCRIPT_URL;
        script.async = true;
        script.addEventListener("load", () => resolve(), { once: true });
        script.addEventListener("error", () => reject(new Error("FluidPlayer 加载失败")), { once: true });
        document.head.appendChild(script);
    });

    return fluidPlayerScriptPromise;
}

/**
 * 销毁播放器实例并吞掉第三方库的重复销毁异常。
 *
 * @param {object|null} player
 * @returns {void}
 */
function destroyPlayer(player) {
    if (!player) {
        return;
    }

    try {
        player.destroy();
    } catch (error) {
        // FluidPlayer 重复销毁时可能抛错，面板关闭流程应继续执行。
    }
}

/**
 * 重建原始 video DOM，避免 FluidPlayer 包裹后的节点影响下一次初始化。
 *
 * @returns {void}
 */
function restoreVideoDOM() {
    const wrapper = document.getElementById("video-wrapper");
    if (!wrapper) {
        return;
    }

    wrapper.innerHTML = `<video id="exoclick-video" style="width: 100%; height: 100%;" playsinline preload="none"><source src="${FALLBACK_VIDEO_SOURCE}" type="video/mp4" /></video>`;
}

/**
 * 创建赚钱面板 Alpine 组件。
 *
 * @returns {object}
 */
export function createEarnPanelData() {
    return {
        isOpen: false,
        status: "idle",
        countdown: "获取中...",
        timer: null,
        player: null,
        videoFinished: false,

        /**
         * 打开面板并提前加载播放器脚本。
         *
         * @returns {void}
         */
        openPanel() {
            this.isOpen = true;
            void loadFluidPlayerScript().catch(() => {
                showToast({ title: "播放器加载失败", message: "广告播放器暂时不可用，请稍后再试。", icon: "⚠️", color: "#ef4444" });
            });

            if (this.status !== "claimed" && this.status !== "claiming") {
                this.resetPanelState();
            }
        },

        /**
         * 关闭面板并释放播放器资源。
         *
         * @returns {void}
         */
        closePanel() {
            this.isOpen = false;
            this.stopTimer();

            if (this.status === "watching") {
                showToast({ title: "取消提示", message: "已取消观看，没有扣除观影次数。", icon: "ℹ️", color: "#3b82f6" });
            }

            destroyPlayer(this.player);
            this.player = null;
            restoreVideoDOM();
            this.status = "idle";
        },

        /**
         * 重置面板到待观看状态。
         *
         * @returns {void}
         */
        resetPanelState() {
            this.status = "idle";
            this.countdown = "获取中...";
            this.videoFinished = false;
            this.stopTimer();
            destroyPlayer(this.player);
            this.player = null;
            restoreVideoDOM();
        },

        /**
         * 领奖后延迟重置，给用户保留到账反馈。
         *
         * @returns {void}
         */
        resetPanel() {
            this.closePanel();
            window.setTimeout(() => {
                this.resetPanelState();
            }, 300);
        },

        /**
         * 标记观看完成并清理播放器。
         *
         * @returns {void}
         */
        completeWatch() {
            this.videoFinished = true;
            this.stopTimer();
            this.status = "completed";
            destroyPlayer(this.player);
            this.player = null;
            restoreVideoDOM();
            window.EffectSounds?.ding?.();
        },

        /**
         * 开始观看广告并启动进度轮询。
         *
         * @returns {Promise<void>}
         */
        async startWatching() {
            this.status = "watching";
            this.countdown = "请求广告...";
            this.videoFinished = false;
            this.stopTimer();

            try {
                await loadFluidPlayerScript();
            } catch (error) {
                this.status = "idle";
                showToast({ title: "播放器加载失败", message: "广告播放器暂时不可用，请稍后再试。", icon: "⚠️", color: "#ef4444" });
                return;
            }

            this.initPlayer();
            let elapsedTime = 0;

            this.timer = window.setInterval(() => {
                if (this.videoFinished) {
                    return;
                }

                const video = document.getElementById("exoclick-video");
                elapsedTime += 0.5;

                if (!video) {
                    return;
                }

                const duration = video.duration;
                const currentTime = video.currentTime;

                if (!Number.isNaN(duration) && duration > 0) {
                    const left = Math.ceil(duration - currentTime);
                    this.countdown = `${left > 0 ? left : 0} 秒`;

                    if (left <= 0 && currentTime > 0) {
                        this.completeWatch();
                    }
                    return;
                }

                // 无广告填充或缓冲过慢时，最多等待 20 秒后放行奖励。
                const fallbackLeft = Math.ceil(20 - elapsedTime);
                if (fallbackLeft > 0) {
                    this.countdown = `缓冲/加载中... ${fallbackLeft}s`;
                    return;
                }

                this.completeWatch();
            }, 500);
        },

        /**
         * 初始化 FluidPlayer 实例。
         *
         * @returns {void}
         */
        initPlayer() {
            const video = document.getElementById("exoclick-video");
            const doInit = () => {
                try {
                    this.player = window.fluidPlayer("exoclick-video", {
                        layoutControls: {
                            primaryColor: "#336699",
                            posterImage: false,
                            playButtonShowing: true,
                            playPauseAnimation: false,
                            fillToContainer: true,
                            autoPlay: true,
                            mute: false,
                        },
                        vastOptions: {
                            allowVPAID: true,
                            vastTimeout: 8000,
                            adList: [
                                {
                                    roll: "preRoll",
                                    vastTag: VAST_TAG_URL,
                                    adText: "请观看广告获取金币",
                                },
                            ],
                        },
                    });
                } catch (error) {
                    // 第三方播放器初始化失败时保留面板，用户可关闭后重试。
                    console.error("[EarnPanel] 播放器初始化未成功", error);
                }
            };

            if (video && !video.paused) {
                video.pause();
                video.addEventListener("pause", doInit, { once: true });
                return;
            }

            doInit();
        },

        /**
         * 停止观看进度计时器。
         *
         * @returns {void}
         */
        stopTimer() {
            if (!this.timer) {
                return;
            }

            window.clearInterval(this.timer);
            this.timer = null;
        },

        /**
         * 向后端领取观看奖励。
         *
         * @returns {Promise<void>}
         */
        async claimReward() {
            if (this.status !== "completed") {
                return;
            }

            this.status = "claiming";

            try {
                const response = await fetch(window.chatContext.earnRewardUrl, {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        "X-CSRF-TOKEN": csrf(),
                        "Accept": "application/json",
                    },
                    body: JSON.stringify({
                        room_id: window.chatContext?.roomId || 0,
                    }),
                });
                const data = await response.json();

                if (response.ok && data.success) {
                    this.status = "claimed";
                    showToast({ title: "奖励到账", message: data.message || "领取成功！", icon: "🎉", color: "#10b981" });

                    if (data.new_jjb !== undefined) {
                        window.chatContext.userJjb = data.new_jjb;
                        window.chatContext.myGold = data.new_jjb;
                        window.dispatchEvent(new CustomEvent("update-user-points", { detail: { points: data.new_jjb } }));
                    }

                    window.EffectSounds?.ding?.();

                    if (data.level_up) {
                        showToast({
                            title: "等级提升",
                            message: `恭喜！您的等级提升到了 ${data.new_level_name}！`,
                            icon: "🌟",
                            color: "#8b5cf6",
                            duration: 5000,
                        });
                        window.setTimeout(() => {
                            window.EffectManager?.play?.("fireworks");
                        }, 500);
                    }
                    return;
                }

                this.status = "completed";
                showToast({ title: "出错了", message: data.message || "领奖失败，请稍后再试。", icon: "❌", color: "#ef4444", duration: 4000 });
            } catch (error) {
                this.status = "completed";
                showToast({ title: "网络错误", message: "网络请求失败，请检查连接。", icon: "⚠️", color: "#ef4444" });
            }
        },
    };
}

/**
 * 注册赚钱面板 Alpine 组件。
 *
 * @returns {void}
 */
function registerEarnPanelData() {
    if (earnPanelRegistered || !window.Alpine) {
        return;
    }

    earnPanelRegistered = true;
    window.Alpine.data("earnPanelData", createEarnPanelData);
}

/**
 * 绑定赚钱面板入口和 Alpine 注册事件。
 *
 * @returns {void}
 */
export function bindEarnPanelControls() {
    if (typeof window === "undefined" || earnPanelControlsBound) {
        return;
    }

    earnPanelControlsBound = true;
    window.createEarnPanelData = createEarnPanelData;
    window.openEarnPanel = () => {
        window.dispatchEvent(new CustomEvent("open-earn-panel"));
    };

    document.addEventListener("alpine:init", registerEarnPanelData, { once: true });
    registerEarnPanelData();
}
