/**
 * 文件功能：聊天室雷电特效
 *
 * 使用递归分叉算法叠加云层闪光、主闪电、余辉残影，
 * 在聊天室中模拟更有压迫感的雷暴闪电效果。
 */

const LightningEffect = (() => {
    /**
     * 递归绘制闪电路径（分裂算法）
     *
     * @param  {CanvasRenderingContext2D}  ctx
     * @param  {number}  x1       起点 x
     * @param  {number}  y1       起点 y
     * @param  {number}  x2       终点 x
     * @param  {number}  y2       终点 y
     * @param  {number}  depth    当前递归深度（控制分叉层数）
     * @param  {number}  width    线条宽度
     */
    function _drawBolt(ctx, x1, y1, x2, y2, depth, width) {
        if (depth <= 0) return;

        // 中点随机偏移（越深层偏移越小，产生流畅感）
        const mx = (x1 + x2) / 2 + (Math.random() - 0.5) * 80 * depth;
        const my = (y1 + y2) / 2 + (Math.random() - 0.5) * 20 * depth;
        const glow = ctx.createLinearGradient(x1, y1, x2, y2);
        glow.addColorStop(0, "rgba(200, 220, 255, 0.9)");
        glow.addColorStop(1, "rgba(150, 180, 255, 0.6)");

        ctx.save();
        ctx.strokeStyle = glow;
        ctx.lineWidth = width;
        ctx.shadowColor = "#aaccff";
        ctx.shadowBlur = 18;
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.quadraticCurveTo(mx, my, x2, y2);
        ctx.stroke();
        ctx.restore();

        // 递归绘制两段子路径
        _drawBolt(ctx, x1, y1, mx, my, depth - 1, width * 0.65);
        _drawBolt(ctx, mx, my, x2, y2, depth - 1, width * 0.65);

        // 随机在中途分叉一条小支路（50% 概率）
        if (depth > 1 && Math.random() > 0.5) {
            const bx = mx + (Math.random() - 0.5) * 120;
            const by = my + Math.random() * 80 + 40;
            _drawBolt(ctx, mx, my, bx, by, depth - 2, width * 0.4);
        }
    }

    /**
     * 绘制顶部乌云压光层，让闪电更有“雷暴”氛围。
     *
     * @param  {HTMLCanvasElement}  canvas
     * @param  {CanvasRenderingContext2D}  ctx
     */
    function _drawStormGlow(canvas, ctx) {
        const w = canvas.width;
        const h = canvas.height;
        const sky = ctx.createLinearGradient(0, 0, 0, h * 0.8);
        sky.addColorStop(0, "rgba(7, 18, 38, 0.34)");
        sky.addColorStop(0.45, "rgba(15, 23, 42, 0.18)");
        sky.addColorStop(1, "rgba(15, 23, 42, 0)");
        ctx.fillStyle = sky;
        ctx.fillRect(0, 0, w, h);

        for (let i = 0; i < 3; i++) {
            const cloudX = w * (0.12 + Math.random() * 0.76);
            const cloudY = h * (0.05 + Math.random() * 0.22);
            const cloudR = 120 + Math.random() * 160;
            const cloud = ctx.createRadialGradient(cloudX, cloudY, 0, cloudX, cloudY, cloudR);
            cloud.addColorStop(0, "rgba(210, 226, 255, 0.18)");
            cloud.addColorStop(0.38, "rgba(168, 196, 255, 0.1)");
            cloud.addColorStop(1, "rgba(168, 196, 255, 0)");
            ctx.fillStyle = cloud;
            ctx.beginPath();
            ctx.arc(cloudX, cloudY, cloudR, 0, Math.PI * 2);
            ctx.fill();
        }
    }

    /**
     * 渲染一次闪电 + 闪屏效果。
     *
     * @param  {HTMLCanvasElement}  canvas
     * @param  {CanvasRenderingContext2D}  ctx
     */
    function _flash(canvas, ctx, timers) {
        const w = canvas.width;
        const h = canvas.height;

        // 清空画布
        ctx.clearRect(0, 0, w, h);

        // 先铺一层压暗天空，再叠加闪白，让明暗反差更明显。
        _drawStormGlow(canvas, ctx);
        ctx.fillStyle = "rgba(228, 239, 255, 0.46)";
        ctx.fillRect(0, 0, w, h);

        // 绘制 1-3 条主闪电，并给出明显的白色核心线。
        const boltCount = Math.floor(Math.random() * 3) + 1;
        for (let i = 0; i < boltCount; i++) {
            const x1 = w * (0.12 + Math.random() * 0.76);
            const y1 = 0;
            const x2 = x1 + (Math.random() - 0.5) * 360;
            const y2 = h * (0.55 + Math.random() * 0.35);
            const width = 3.6 + Math.random() * 1.8;
            _drawBolt(ctx, x1, y1, x2, y2, 5, width);

            ctx.save();
            ctx.strokeStyle = "rgba(255,255,255,0.92)";
            ctx.lineWidth = Math.max(1.2, width * 0.34);
            ctx.shadowColor = "rgba(255,255,255,0.95)";
            ctx.shadowBlur = 22;
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.stroke();
            ctx.restore();
        }

        // 短促残影：闪电消失后保留一层很淡的余辉，避免“闪一下就没了”。
        timers.push(setTimeout(() => {
            ctx.clearRect(0, 0, w, h);
            _drawStormGlow(canvas, ctx);
            ctx.fillStyle = "rgba(185, 205, 255, 0.12)";
            ctx.fillRect(0, 0, w, h);
        }, 90));

        timers.push(setTimeout(() => {
            ctx.clearRect(0, 0, w, h);
        }, 190));
    }

    /**
     * 启动雷电特效
     *
     * @param  {HTMLCanvasElement}  canvas   全屏 Canvas
     * @param  {Function}           onEnd    特效结束回调
     */
    function start(canvas, onEnd) {
        const ctx = canvas.getContext("2d");
        const FLASHES = 9;
        const DURATION = 7600;
        let count = 0;
        let finished = false;
        const timers = [];

        /**
         * 统一结束特效，避免多次触发 onEnd。
         */
        function finish() {
            if (finished) {
                return;
            }

            finished = true;
            timers.forEach((timer) => clearTimeout(timer));
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            onEnd();
        }

        // 间隔不规则触发多次闪电（模拟真实雷电节奏）
        function nextFlash() {
            if (count >= FLASHES) {
                timers.push(setTimeout(() => {
                    finish();
                }, 520));
                return;
            }

            _flash(canvas, ctx, timers);
            count++;

            // 让雷电节奏有“成组爆发”的感觉：有时连续两下，有时间隔更久。
            const delay = Math.random() > 0.65
                ? 140 + Math.random() * 140
                : 420 + Math.random() * 520;
            timers.push(setTimeout(nextFlash, delay));
        }

        // 短暂延迟后开始第一次闪电
        timers.push(setTimeout(nextFlash, 300));

        // 安全兜底：超时强制结束
        timers.push(setTimeout(() => {
            finish();
        }, DURATION + 500));

        return {
            cancel() {
                if (finished) {
                    return;
                }

                finished = true;
                timers.forEach((timer) => clearTimeout(timer));
                ctx.clearRect(0, 0, canvas.width, canvas.height);
            },
        };
    }

    return { start };
})();

window.LightningEffect = LightningEffect;
