/**
 * 文件功能：聊天室下雨特效
 *
 * 使用 Canvas 绘制斜向雨线，模拟真实降雨视觉效果。
 * 加粗加深雨线颜色，在浅色背景上清晰可见。
 * 特效总时长约 8 秒，结束后自动清理并回调。
 */

const RainEffect = (() => {
    // 雨滴类：一条从顶部往下落的斜线
    class Drop {
        constructor(w, h) {
            this.reset(w, h);
        }

        /**
         * 重置/初始化雨滴位置
         */
        reset(w, h) {
            this.x = Math.random() * w;
            this.y = Math.random() * -h;
            this.len = Math.random() * 25 + 12; // 雨线长度（稍加长）
            this.speed = Math.random() * 10 + 7; // 下落速度（加快）
            this.angle = (Math.PI / 180) * (75 + Math.random() * 10);
            this.alpha = Math.random() * 0.5 + 0.4; // 提高透明度上限 (0.4-0.9，原 0.2-0.5)
            this.strokeW = Math.random() * 1.5 + 0.8; // 线条宽度随机（原 0.8 固定）
            this.w = w;
            this.h = h;
        }

        /** 每帧更新雨滴位置 */
        update() {
            this.x += Math.cos(this.angle) * this.speed * 0.3;
            this.y += Math.sin(this.angle) * this.speed;
            if (this.y > this.h + this.len) {
                this.reset(this.w, this.h);
            }
        }

        /** 绘制雨滴线段（加深蓝色，在浅色背景上更明显） */
        draw(ctx) {
            ctx.save();
            ctx.strokeStyle = `rgba(50, 130, 220, ${this.alpha})`; // 加深蓝色（原浅蓝 155,200,255）
            ctx.lineWidth = this.strokeW;
            ctx.shadowColor = "rgba(30, 100, 200, 0.4)";
            ctx.shadowBlur = 2;
            ctx.beginPath();
            ctx.moveTo(this.x, this.y);
            ctx.lineTo(
                this.x + Math.cos(this.angle) * this.len,
                this.y + Math.sin(this.angle) * this.len,
            );
            ctx.stroke();
            ctx.restore();
        }
    }

    /**
     * 启动下雨特效
     *
     * @param  {HTMLCanvasElement}  canvas   全屏 Canvas
     * @param  {Function}           onEnd    特效结束回调
     */
    function start(canvas, onEnd) {
        const ctx = canvas.getContext("2d");
        const w = canvas.width;
        const h = canvas.height;
        const DURATION = 8000;
        const isMobile = window.matchMedia?.("(max-width: 640px)")?.matches || window.innerWidth <= 640;
        const DROP_COUNT = isMobile ? 130 : 200; // 移动端降低雨线数量，避免满屏线段拖慢滚动和输入。

        const drops = Array.from({ length: DROP_COUNT }, () => {
            const d = new Drop(w, h);
            d.y = Math.random() * h;
            return d;
        });

        let animId = null;
        let finished = false;
        const startTime = performance.now();

        /**
         * 统一结束雨滴动画，手动取消时不触发队列续播。
         *
         * @param {boolean} canceled 是否为手动取消
         */
        function finish(canceled) {
            if (finished) {
                return;
            }

            finished = true;
            if (animId) {
                cancelAnimationFrame(animId);
            }
            ctx.clearRect(0, 0, w, h);
            if (!canceled) {
                onEnd();
            }
        }

        function animate(now) {
            // 清除画布（透明，不遮挡聊天背景）
            ctx.clearRect(0, 0, w, h);

            drops.forEach((d) => {
                d.update();
                d.draw(ctx);
            });

            if (now - startTime < DURATION) {
                animId = requestAnimationFrame(animate);
            } else {
                finish(false);
            }
        }

        animId = requestAnimationFrame(animate);
        return {
            cancel() {
                finish(true);
            },
        };
    }

    return { start };
})();

window.RainEffect = RainEffect;
