/**
 * 文件功能：聊天室樱花飘落特效
 *
 * 使用 Canvas 绘制多层粉色花瓣，让花瓣在屏幕上方生成后缓慢下落、
 * 左右摆动并带轻微旋转，营造柔和的春日氛围。
 */

const SakuraEffect = (() => {
    class Petal {
        constructor(w, h) {
            this.w = w;
            this.h = h;
            this.reset(true);
        }

        /**
         * 重置花瓣位置与运动参数。
         *
         * @param {boolean} initial 是否首次初始化
         */
        reset(initial = false) {
            this.x = Math.random() * this.w;
            this.y = initial ? Math.random() * this.h : -20;
            this.size = Math.random() * 7 + 8;
            this.speedY = Math.random() * 1.1 + 0.7;
            this.speedX = Math.random() * 0.6 - 0.3;
            this.swing = Math.random() * Math.PI * 2;
            this.swingSpeed = Math.random() * 0.03 + 0.01;
            this.rotation = Math.random() * Math.PI * 2;
            this.rotationSpeed = (Math.random() - 0.5) * 0.03;
            this.alpha = Math.random() * 0.25 + 0.55;
            this.color = ["#fbcfe8", "#f9a8d4", "#fda4af", "#fce7f3"][
                Math.floor(Math.random() * 4)
            ];
        }

        /**
         * 更新花瓣运动状态。
         */
        update() {
            this.swing += this.swingSpeed;
            this.rotation += this.rotationSpeed;
            this.x += this.speedX + Math.sin(this.swing) * 0.75;
            this.y += this.speedY;

            if (this.y > this.h + 30 || this.x < -30 || this.x > this.w + 30) {
                this.reset(false);
            }
        }

        /**
         * 绘制单片樱花花瓣。
         *
         * @param {CanvasRenderingContext2D} ctx
         */
        draw(ctx) {
            ctx.save();
            ctx.translate(this.x, this.y);
            ctx.rotate(this.rotation);
            ctx.globalAlpha = this.alpha;
            ctx.fillStyle = this.color;
            ctx.shadowColor = "rgba(244, 114, 182, 0.35)";
            ctx.shadowBlur = 8;

            ctx.beginPath();
            ctx.moveTo(0, -this.size * 0.9);
            ctx.quadraticCurveTo(this.size * 0.9, -this.size * 0.25, 0, this.size);
            ctx.quadraticCurveTo(-this.size * 0.9, -this.size * 0.25, 0, -this.size * 0.9);
            ctx.fill();

            ctx.strokeStyle = "rgba(190, 24, 93, 0.25)";
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.moveTo(0, -this.size * 0.55);
            ctx.lineTo(0, this.size * 0.7);
            ctx.stroke();
            ctx.restore();
        }
    }

    /**
     * 启动樱花特效。
     *
     * @param {HTMLCanvasElement} canvas
     * @param {Function} onEnd
     */
    function start(canvas, onEnd) {
        const ctx = canvas.getContext("2d");
        const w = canvas.width;
        const h = canvas.height;
        const DURATION = 10000;
        const PETAL_COUNT = Math.min(58, Math.max(34, Math.floor(w / 28)));
        const petals = Array.from({ length: PETAL_COUNT }, () => new Petal(w, h));
        const startTime = performance.now();
        let animId = null;
        let finished = false;

        /**
         * 统一结束樱花动画，手动取消时只清理不回调。
         *
         * @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);

            petals.forEach((petal) => {
                petal.update();
                petal.draw(ctx);
            });

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

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

    return { start };
})();

window.SakuraEffect = SakuraEffect;
