/**
 * 文件功能：聊天室 99A 主战坦克重装入场特效
 *
 * 使用全屏透明 Canvas 绘制中国 99A 主战坦克横穿屏幕、履带滚动、
 * 长炮管炮击、楔形复合装甲、侧裙、尘土冲击波与重装入场 HUD。
 */

const Type99AEffect = (() => {
    const DURATION = 8200;
    const ARMOR = "#5f6f3a";
    const DARK_ARMOR = "#1f2a1d";
    const CAMO = "#7c6a36";
    const DUST = "#fde68a";
    const FIRE = "#f97316";

    /**
     * 缓出曲线，让坦克进场有重量感。
     *
     * @param {number} t 0 到 1 的进度
     * @returns {number}
     */
    function easeOutCubic(t) {
        return 1 - Math.pow(1 - t, 3);
    }

    /**
     * 缓入缓出曲线，用于 HUD 和冲击波。
     *
     * @param {number} t 0 到 1 的进度
     * @returns {number}
     */
    function easeInOutSine(t) {
        return -(Math.cos(Math.PI * t) - 1) / 2;
    }

    /**
     * 创建地面尘土粒子。
     *
     * @param {number} w 画布宽度
     * @param {number} h 画布高度
     * @returns {Array<Record<string, number>>}
     */
    function createDust(w, h) {
        return Array.from({ length: 90 }, () => ({
            x: Math.random() * w,
            y: h * (0.66 + Math.random() * 0.18),
            speed: 1.6 + Math.random() * 4.8,
            size: 2 + Math.random() * 8,
            alpha: 0.12 + Math.random() * 0.34,
        }));
    }

    /**
     * 绘制战场式地面背景。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} w 画布宽度
     * @param {number} h 画布高度
     * @param {number} progress 播放进度
     */
    function drawBackdrop(ctx, w, h, progress) {
        const fade = Math.min(1, progress / 0.16) * Math.min(1, (1 - progress) / 0.12);
        const gradient = ctx.createRadialGradient(w * 0.5, h * 0.62, 0, w * 0.5, h * 0.62, Math.max(w, h) * 0.76);
        gradient.addColorStop(0, `rgba(41,37,36,${0.42 * fade})`);
        gradient.addColorStop(0.55, `rgba(63,98,18,${0.18 * fade})`);
        gradient.addColorStop(1, "rgba(0,0,0,0)");

        ctx.save();
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);
        ctx.globalCompositeOperation = "lighter";

        for (let i = 0; i < 8; i++) {
            const y = h * (0.7 + i * 0.028);
            ctx.strokeStyle = `rgba(253,230,138,${0.1 * fade})`;
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.moveTo(0, y + Math.sin(progress * 12 + i) * 4);
            ctx.lineTo(w, y + Math.cos(progress * 9 + i) * 4);
            ctx.stroke();
        }

        ctx.restore();
    }

    /**
     * 绘制履带带起的尘土。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {Array<Record<string, number>>} dust 尘土粒子
     * @param {number} w 画布宽度
     * @param {number} progress 播放进度
     */
    function drawDust(ctx, dust, w, progress) {
        const fade = Math.min(1, progress / 0.18) * Math.min(1, (1 - progress) / 0.12);

        ctx.save();
        ctx.globalCompositeOperation = "lighter";
        dust.forEach((particle, index) => {
            const travel = (progress * (620 + particle.speed * 80) + index * 47) % (w + 420);
            const x = w + 210 - travel;
            ctx.globalAlpha = particle.alpha * fade;
            ctx.fillStyle = DUST;
            ctx.shadowColor = DUST;
            ctx.shadowBlur = particle.size * 1.4;
            ctx.beginPath();
            ctx.ellipse(x, particle.y, particle.size * 1.8, particle.size * 0.7, 0, 0, Math.PI * 2);
            ctx.fill();
        });
        ctx.restore();
    }

    /**
     * 绘制炮击冲击波。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} w 画布宽度
     * @param {number} h 画布高度
     * @param {number} progress 播放进度
     */
    function drawShockwave(ctx, w, h, progress) {
        const shot = Math.max(0, Math.min(1, (progress - 0.5) / 0.2));
        if (shot <= 0 || shot >= 1) {
            return;
        }

        const alpha = Math.sin(shot * Math.PI);
        ctx.save();
        ctx.globalCompositeOperation = "lighter";
        ctx.strokeStyle = `rgba(253,230,138,${0.38 * alpha})`;
        ctx.lineWidth = 5;
        ctx.beginPath();
        ctx.ellipse(w * 0.48, h * 0.68, w * (0.08 + shot * 0.38), h * (0.03 + shot * 0.08), 0, 0, Math.PI * 2);
        ctx.stroke();
        ctx.restore();
    }

    /**
     * 绘制 99A 主炮炮口火焰。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} progress 播放进度
     */
    function drawMuzzleFlash(ctx, progress) {
        const flash = Math.max(0, 1 - Math.abs(progress - 0.5) / 0.045);
        if (flash <= 0) {
            return;
        }

        ctx.save();
        ctx.globalCompositeOperation = "lighter";
        ctx.shadowColor = FIRE;
        ctx.shadowBlur = 28;
        ctx.fillStyle = `rgba(249,115,22,${0.78 * flash})`;
        ctx.beginPath();
        ctx.moveTo(408, -118);
        ctx.lineTo(528, -156);
        ctx.lineTo(468, -112);
        ctx.lineTo(532, -76);
        ctx.lineTo(408, -100);
        ctx.closePath();
        ctx.fill();

        ctx.fillStyle = `rgba(255,255,255,${0.74 * flash})`;
        ctx.beginPath();
        ctx.moveTo(414, -114);
        ctx.lineTo(486, -132);
        ctx.lineTo(452, -108);
        ctx.lineTo(492, -92);
        ctx.lineTo(414, -102);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }

    /**
     * 绘制 99A 主战坦克主体。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} x 坦克中心 x
     * @param {number} y 坦克中心 y
     * @param {number} scale 缩放比例
     * @param {number} progress 播放进度
     */
    function drawTank(ctx, x, y, scale, progress) {
        ctx.save();
        ctx.translate(x, y);
        ctx.scale(scale, scale);

        ctx.save();
        ctx.shadowColor = "rgba(0,0,0,0.72)";
        ctx.shadowBlur = 16;
        ctx.fillStyle = "rgba(0,0,0,0.45)";
        ctx.beginPath();
        ctx.ellipse(0, 54, 250, 22, 0, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();

        drawMuzzleFlash(ctx, progress);

        // 99A 履带底盘：右侧前导轮更大，模拟参考图的右前方视角。
        const track = ctx.createLinearGradient(-246, 24, 246, 94);
        track.addColorStop(0, "#0a0a0a");
        track.addColorStop(0.42, DARK_ARMOR);
        track.addColorStop(1, "#030712");
        ctx.fillStyle = track;
        ctx.beginPath();
        ctx.moveTo(-250, 32);
        ctx.lineTo(-206, 10);
        ctx.lineTo(184, 12);
        ctx.lineTo(252, 38);
        ctx.lineTo(218, 94);
        ctx.lineTo(-226, 96);
        ctx.lineTo(-270, 70);
        ctx.closePath();
        ctx.fill();

        ctx.fillStyle = "rgba(15,23,42,0.74)";
        ctx.beginPath();
        ctx.moveTo(-236, 22);
        ctx.lineTo(180, 23);
        ctx.lineTo(236, 43);
        ctx.lineTo(204, 62);
        ctx.lineTo(-218, 58);
        ctx.lineTo(-256, 42);
        ctx.closePath();
        ctx.fill();

        for (let i = 0; i < 7; i++) {
            const wheelX = -180 + i * 58;
            const wheelY = 62 + (i > 4 ? 2 : 0);
            drawRoadWheel(ctx, wheelX, wheelY, progress + i * 0.05);
        }

        ctx.strokeStyle = "rgba(253,230,138,0.14)";
        ctx.lineWidth = 4;
        ctx.beginPath();
        ctx.moveTo(-218, 82);
        ctx.lineTo(212, 82);
        ctx.stroke();

        // 99A 车体：右侧为前装甲，首上装甲呈明显楔形下压。
        const hull = ctx.createLinearGradient(-238, -50, 250, 36);
        hull.addColorStop(0, "#42512b");
        hull.addColorStop(0.38, ARMOR);
        hull.addColorStop(0.66, CAMO);
        hull.addColorStop(1, "#253018");
        ctx.fillStyle = hull;
        ctx.beginPath();
        ctx.moveTo(-238, 24);
        ctx.lineTo(-212, -30);
        ctx.lineTo(86, -52);
        ctx.lineTo(226, -24);
        ctx.lineTo(252, 14);
        ctx.lineTo(202, 38);
        ctx.lineTo(-216, 36);
        ctx.closePath();
        ctx.fill();

        ctx.fillStyle = "rgba(15,23,42,0.34)";
        ctx.beginPath();
        ctx.moveTo(68, -44);
        ctx.lineTo(226, -22);
        ctx.lineTo(248, 9);
        ctx.lineTo(138, 18);
        ctx.lineTo(86, -5);
        ctx.closePath();
        ctx.fill();

        // 侧裙装甲模块和数码迷彩块，增强 99A 识别度。
        for (let i = 0; i < 8; i++) {
            const panelX = -206 + i * 50;
            ctx.fillStyle = i % 2 === 0 ? "rgba(54,83,20,0.86)" : "rgba(120,113,55,0.82)";
            ctx.fillRect(panelX, -2, 42, 24);
            ctx.strokeStyle = "rgba(15,23,42,0.34)";
            ctx.lineWidth = 1.4;
            ctx.strokeRect(panelX, -2, 42, 24);
        }

        [
            [-186, -24, 34, 18, "#7f8f57"],
            [-118, -34, 42, 20, "#b9855a"],
            [-32, -39, 48, 22, "#344329"],
            [52, -46, 44, 20, "#8a9b61"],
            [118, -30, 38, 19, "#a36f52"],
            [182, -14, 46, 21, "#415329"],
            [-220, 2, 30, 20, "#27351f"],
            [-72, 4, 36, 18, "#718246"],
            [22, 2, 42, 20, "#ac7654"],
        ].forEach(([px, py, pw, ph, color]) => {
            ctx.fillStyle = color;
            ctx.fillRect(px, py, pw, ph);
        });

        // 参考图里的大号车号、国旗和前车灯。
        ctx.fillStyle = "rgba(255,255,255,0.9)";
        ctx.font = "900 31px serif";
        ctx.fillText("807", -216, -12);
        ctx.fillStyle = "rgba(220,38,38,0.95)";
        ctx.fillRect(-128, -31, 34, 22);
        ctx.fillStyle = "rgba(253,224,71,0.95)";
        ctx.font = "900 12px serif";
        ctx.fillText("★", -122, -16);
        ctx.fillStyle = "rgba(254,242,242,0.88)";
        roundRect(ctx, 178, -17, 18, 9, 5);
        ctx.fill();
        roundRect(ctx, 214, -8, 18, 9, 5);
        ctx.fill();

        // 低矮楔形炮塔和 125mm 长炮管：炮管朝右并略微上扬。
        const turret = ctx.createLinearGradient(-128, -108, 156, -28);
        turret.addColorStop(0, "#66734a");
        turret.addColorStop(0.46, "#87905d");
        turret.addColorStop(1, "#24301d");
        ctx.fillStyle = turret;
        ctx.beginPath();
        ctx.moveTo(-132, -36);
        ctx.lineTo(-82, -96);
        ctx.lineTo(86, -108);
        ctx.lineTo(158, -72);
        ctx.lineTo(112, -32);
        ctx.lineTo(-118, -20);
        ctx.closePath();
        ctx.fill();

        [
            [-98, -76, 42, 22, "#314222"],
            [-28, -90, 50, 22, "#a36f52"],
            [46, -92, 48, 20, "#73844d"],
            [98, -66, 34, 20, "#2f3f24"],
        ].forEach(([px, py, pw, ph, color]) => {
            ctx.fillStyle = color;
            ctx.fillRect(px, py, pw, ph);
        });

        ctx.save();
        ctx.strokeStyle = "rgba(17,24,39,0.96)";
        ctx.lineWidth = 18;
        ctx.lineCap = "round";
        ctx.beginPath();
        ctx.moveTo(106, -70);
        ctx.lineTo(410, -120);
        ctx.stroke();
        ctx.strokeStyle = "#64748b";
        ctx.lineWidth = 6;
        ctx.beginPath();
        ctx.moveTo(114, -75);
        ctx.lineTo(404, -123);
        ctx.stroke();
        ctx.fillStyle = "#1f2937";
        roundRect(ctx, 392, -132, 30, 24, 8);
        ctx.fill();
        ctx.fillStyle = "#40513a";
        roundRect(ctx, 250, -107, 24, 20, 5);
        ctx.fill();
        roundRect(ctx, 322, -120, 24, 20, 5);
        ctx.fill();
        ctx.restore();

        ctx.fillStyle = "rgba(17,24,39,0.95)";
        roundRect(ctx, 86, -80, 62, 24, 8);
        ctx.fill();

        // 炮塔前装甲、烟幕弹发射器和车长机枪。
        ctx.fillStyle = "rgba(15,23,42,0.5)";
        ctx.beginPath();
        ctx.moveTo(42, -48);
        ctx.lineTo(96, -78);
        ctx.lineTo(154, -66);
        ctx.lineTo(112, -36);
        ctx.closePath();
        ctx.fill();

        for (let i = 0; i < 4; i++) {
            ctx.fillStyle = "rgba(15,23,42,0.9)";
            roundRect(ctx, -124 + i * 13, -58 + (i % 2) * 10, 10, 18, 4);
            ctx.fill();
        }

        ctx.strokeStyle = "rgba(15,23,42,0.9)";
        ctx.lineWidth = 3;
        ctx.beginPath();
        ctx.moveTo(-24, -102);
        ctx.lineTo(-18, -132);
        ctx.lineTo(40, -138);
        ctx.stroke();

        ctx.fillStyle = "rgba(15,23,42,0.84)";
        roundRect(ctx, -32, -108, 58, 14, 7);
        ctx.fill();

        // 装甲高光。
        ctx.strokeStyle = "rgba(226,232,240,0.28)";
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(-184, -22);
        ctx.lineTo(92, -40);
        ctx.moveTo(-142, 8);
        ctx.lineTo(172, -2);
        ctx.moveTo(92, -82);
        ctx.lineTo(144, -66);
        ctx.stroke();

        ctx.restore();
    }

    /**
     * 绘制坦克负重轮。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} x 中心 x
     * @param {number} y 中心 y
     * @param {number} progress 播放进度
     */
    function drawRoadWheel(ctx, x, y, progress) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(progress * 30);
        ctx.fillStyle = "#111827";
        ctx.beginPath();
        ctx.arc(0, 0, 21, 0, Math.PI * 2);
        ctx.fill();
        ctx.strokeStyle = "#475569";
        ctx.lineWidth = 3;
        ctx.stroke();
        ctx.strokeStyle = "#94a3b8";
        ctx.lineWidth = 2;
        for (let i = 0; i < 6; i++) {
            ctx.rotate(Math.PI / 3);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(16, 0);
            ctx.stroke();
        }
        ctx.fillStyle = "#cbd5e1";
        ctx.beginPath();
        ctx.arc(0, 0, 5, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();
    }

    /**
     * 绘制 99A 重装入场 HUD 字幕。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} w 画布宽度
     * @param {number} h 画布高度
     * @param {number} progress 播放进度
     * @param {string} title 入场标题
     * @param {string} userInfo 用户身份信息
     */
    function drawHud(ctx, w, h, progress, title, userInfo) {
        const enter = Math.min(1, Math.max(0, (progress - 0.14) / 0.2));
        const leave = Math.min(1, Math.max(0, (1 - progress) / 0.16));
        const alpha = easeInOutSine(enter) * leave;
        const y = h * 0.17 - (1 - enter) * 24;

        ctx.save();
        ctx.globalAlpha = alpha;
        ctx.textAlign = "center";
        ctx.shadowColor = "rgba(253,230,138,0.95)";
        ctx.shadowBlur = 22;
        ctx.fillStyle = "rgba(28,25,23,0.66)";
        ctx.strokeStyle = "rgba(253,230,138,0.72)";
        ctx.lineWidth = 2;
        roundRect(ctx, w * 0.5 - 340, y - 56, 680, 120, 18);
        ctx.fill();
        ctx.stroke();

        ctx.fillStyle = "#fef3c7";
        ctx.font = "700 16px serif";
        ctx.fillText("ZTZ-99A ARMORED FORCE", w * 0.5, y - 24);
        ctx.fillStyle = "#fde68a";
        ctx.font = "700 18px serif";
        ctx.fillText(userInfo, w * 0.5, y + 8, 620);
        ctx.fillStyle = "#ffffff";
        ctx.font = "900 34px serif";
        ctx.fillText(title, w * 0.5, y + 45, 620);
        ctx.restore();
    }

    /**
     * 绘制圆角矩形路径。
     *
     * @param {CanvasRenderingContext2D} ctx Canvas 上下文
     * @param {number} x 左上角 x
     * @param {number} y 左上角 y
     * @param {number} w 宽度
     * @param {number} h 高度
     * @param {number} r 圆角半径
     */
    function roundRect(ctx, x, y, w, h, r) {
        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.lineTo(x + w - r, y);
        ctx.quadraticCurveTo(x + w, y, x + w, y + r);
        ctx.lineTo(x + w, y + h - r);
        ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
        ctx.lineTo(x + r, y + h);
        ctx.quadraticCurveTo(x, y + h, x, y + h - r);
        ctx.lineTo(x, y + r);
        ctx.quadraticCurveTo(x, y, x + r, y);
        ctx.closePath();
    }

    /**
     * 启动 99A 主战坦克重装入场特效。
     *
     * @param {HTMLCanvasElement} canvas 全屏特效画布
     * @param {Function} onEnd 结束回调
     * @param {object} options 特效附加参数
     * @returns {{cancel: Function}}
     */
    function start(canvas, onEnd, options = {}) {
        const ctx = canvas.getContext("2d");
        const w = canvas.width;
        const h = canvas.height;
        const dust = createDust(w, h);
        const title = String(options.effect_title || "99A主战坦克 重装入场").trim() || "99A主战坦克 重装入场";
        const userInfo = String(options.effect_user_info || "").trim();
        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();
            }
        }

        /**
         * 逐帧绘制坦克入场动画。
         *
         * @param {number} now 当前高精度时间
         */
        function animate(now) {
            const elapsed = now - startTime;
            const progress = Math.min(1, elapsed / DURATION);
            const entry = easeOutCubic(Math.min(1, progress / 0.64));
            const exit = easeInOutSine(Math.max(0, (progress - 0.76) / 0.24));
            const tankX = -w * 0.24 + entry * w * 0.92 + exit * w * 0.62;
            const tankY = h * 0.66 + Math.sin(progress * 24) * 2.5;
            const scale = Math.min(1.12, Math.max(0.68, w / 1180));

            ctx.clearRect(0, 0, w, h);
            drawBackdrop(ctx, w, h, progress);
            drawDust(ctx, dust, w, progress);
            drawShockwave(ctx, w, h, progress);
            drawTank(ctx, tankX, tankY, scale, progress);
            drawHud(ctx, w, h, progress, title, userInfo);

            if (progress < 1) {
                animId = requestAnimationFrame(animate);
            } else {
                finish(false);
            }
        }

        animId = requestAnimationFrame(animate);

        return {
            cancel() {
                finish(true);
            },
        };
    }

    return { start };
})();

window.Type99AEffect = Type99AEffect;
