import { world, system, ItemStack } from "@minecraft/server";
import { ModalFormData } from "@minecraft/server-ui";

// プレイヤーごとのコンボ記録用マップ
const playerCombos = new Map();

// 重さ（クラッシュ）対策: 同時に昇天・爆発処理を行うMobの最大数
const MAX_ASCENDING_MOBS = 10;
let currentAscendingMobs = 0;

// 雷魔法アイテムの名前定義
const MAGIC_NAME_JA = "§e超スーパーウルトラハイパーめっちゃすごい雷魔法§r";
const MAGIC_NAME_EN = "§eSuper Ultra Hyper Mega Insane Lightning Magic§r";

// 【重要修正】スクリプト読み込み時に、エラーでスタックした「チャージ中」のタグを全員から剥がす
system.run(() => {
    for (const player of world.getAllPlayers()) {
        try { player.removeTag("overkill_charging"); } catch (e) {}
    }
});

// 初回ログイン時に使い捨ての設定本を付与
world.afterEvents.playerSpawn.subscribe((event) => {
    const player = event.player;
    try { player.removeTag("overkill_charging"); } catch (e) {} // 念のためスポーン時にも剥がす

    if (!event.initialSpawn) return; // ワールドに入った最初の1回だけ
    
    if (!player.hasTag("overkill_joined")) {
        player.addTag("overkill_joined");
        // 【変更】魔法はデフォルトでオフにするため、初回参加時にオフ用のタグを付与
        player.addTag("overkill_magic_off");
        
        try {
            const inventory = player.getComponent("minecraft:inventory").container;
            if (inventory) {
                const book = new ItemStack("minecraft:book", 1);
                book.nameTag = "§dOverkill Settings / 設定本§r";
                book.setLore([
                    "Right-click/Hold to open settings.", 
                    "(右クリック/長押しで設定を開く)",
                    "*Consumed on use, returns if canceled.",
                    "(※使用すると消滅しますがキャンセルで戻ります)",
                    "*Type '!overkill' in chat to get again.",
                    "(※「!overkill」とチャットでも再取得可能)"
                ]);
                inventory.addItem(book);
            }
        } catch (e) {}
    }
});

// チャットコマンドで設定本を再取得
world.beforeEvents.chatSend.subscribe((event) => {
    if (event.message === "!overkill") {
        event.cancel = true;
        const player = event.sender;
        const isJapanese = player.hasTag("overkill_lang_ja");
        
        system.run(() => {
            try {
                const inventory = player.getComponent("minecraft:inventory").container;
                if (inventory) {
                    const book = new ItemStack("minecraft:book", 1);
                    book.nameTag = isJapanese ? "§dOverkill設定本(使い捨て)§r" : "§dOverkill Settings Book§r";
                    book.setLore(isJapanese ? [
                        "右クリック/長押しで設定を開く", 
                        "※使用すると消滅しますがキャンセルで戻ります",
                        "※「!overkill」とチャットでも再取得可能"
                    ] : [
                        "Right-click/Hold to open settings.", 
                        "*Consumed on use, returns if canceled.",
                        "*Type '!overkill' in chat to get again."
                    ]);
                    inventory.addItem(book);
                    player.sendMessage(isJapanese ? "§a[Overkill Party] 設定本を再付与しました。§r" : "§a[Overkill Party] Settings book granted.§r");
                }
            } catch (e) {}
        });
    }
});

// 【修正】空クリック(itemUse)とブロッククリック(itemUseOn)の両方に対応する共通ハンドラー
function handleItemClick(event) {
    const player = event.source;
    const item = event.itemStack;
    if (!item) return;

    // --- 設定本の使用検知 ---
    if (item.typeId === "minecraft:book" && (item.nameTag === "§dOverkill Settings Book§r" || item.nameTag === "§dOverkill設定本(使い捨て)§r" || item.nameTag === "§dOverkill Settings / 設定本§r")) {
        try { event.cancel = true; } catch (e) {} // afterEventsではエラーになるため安全対策
        system.run(() => {
            try {
                const inventory = player.getComponent("minecraft:inventory").container;
                if (inventory) {
                    for (let i = 0; i < inventory.size; i++) {
                        const currentItem = inventory.getItem(i);
                        if (currentItem && currentItem.typeId === "minecraft:book" && (currentItem.nameTag === "§dOverkill Settings Book§r" || currentItem.nameTag === "§dOverkill設定本(使い捨て)§r" || currentItem.nameTag === "§dOverkill Settings / 設定本§r")) {
                            if (currentItem.amount > 1) {
                                currentItem.amount -= 1;
                                inventory.setItem(i, currentItem);
                            } else {
                                inventory.setItem(i, undefined);
                            }
                            break;
                        }
                    }
                }
            } catch (e) {}
            showSettingsUI(player);
        });
    }

    // --- 雷魔法の使用検知 ---
    if (item.typeId === "minecraft:blaze_rod" && (item.nameTag === MAGIC_NAME_JA || item.nameTag === MAGIC_NAME_EN)) {
        try { event.cancel = true; } catch (e) {}
        
        // 既にチャージ中なら何もしない
        if (player.hasTag("overkill_charging")) return;

        system.run(() => {
            // 魔法アイテムを消費する
            try {
                const inventory = player.getComponent("minecraft:inventory").container;
                if (inventory) {
                    for (let i = 0; i < inventory.size; i++) {
                        const currentItem = inventory.getItem(i);
                        if (currentItem && currentItem.typeId === "minecraft:blaze_rod" && (currentItem.nameTag === MAGIC_NAME_JA || currentItem.nameTag === MAGIC_NAME_EN)) {
                            if (currentItem.amount > 1) {
                                currentItem.amount -= 1;
                                inventory.setItem(i, currentItem);
                            } else {
                                inventory.setItem(i, undefined);
                            }
                            break;
                        }
                    }
                }
            } catch (e) {}
            
            // 魔法のチャージ開始！
            castUltimateMagic(player);
        });
    }
}

// 【重要修正】APIバージョンによるエラーを防ぐため、afterEventsを使用し安全に登録
try { world.afterEvents.itemUse.subscribe(handleItemClick); } catch (e) {}
try { world.afterEvents.itemUseOn.subscribe(handleItemClick); } catch (e) {}


// 設定UIの表示関数
function showSettingsUI(player) {
    const form = new ModalFormData();
    
    // 現在の設定をタグから読み取る (タグがない状態 = ON)
    const isJapanese = player.hasTag("overkill_lang_ja");
    const isFriendlyOn = !player.hasTag("overkill_friendly_off");
    const isPluginOn = !player.hasTag("overkill_off");
    const isAscendOn = !player.hasTag("overkill_ascend_off");
    const isTitleOn = !player.hasTag("overkill_title_off");
    const isShakeOn = !player.hasTag("overkill_shake_off");
    const isEffectOn = !player.hasTag("overkill_effect_off");
    const isMagicOn = !player.hasTag("overkill_magic_off"); // タグがない＝ON（初期状態はタグありでOFF）

    const t = isJapanese ? {
        title: "Overkill Party 設定",
        lang: "言語 / Language (変更して保存すると即座に切り替わります)",
        friendly: "友好Mobを対象にする\n[ヘルプ] オンにすると動物や村人などの非敵対Mobも打ち上げとコンボの対象になります。",
        plugin: "システム全体の有効化\n[ヘルプ] アドオン自体のオン/オフを切り替えます。",
        ascend: "Mobの打ち上げ・爆発演出\n[ヘルプ] 倒したMobが空へ打ち上がり爆発する演出のオン/オフ。",
        comboTitle: "コンボ時のタイトル表示\n[ヘルプ] 連続キル時に画面に表示されるタイトルのオン/オフ。",
        shake: "画面の激しい揺れ(CameraShake)\n[ヘルプ] 高コンボ時に画面が揺れる演出のオン/オフ。",
        effect: "派手なエフェクト(雷・花火など)\n[ヘルプ] 花火、雷、空襲サイレンなどの過剰なエフェクトのオン/オフ。",
        magic: "30コンボで超絶雷魔法を付与\n[ヘルプ] (デフォルト:オフ) 30連続キル達成時に、広範囲を焦土と化す魔法を獲得します。",
        save: "§a[Overkill Party] 設定を保存しました。§r",
        lore: ["右クリック/長押しで設定を開く", "※使用すると消滅しますがキャンセルで戻ります", "※「!overkill」とチャットでも再取得可能"]
    } : {
        title: "Overkill Party Settings",
        lang: "Language / 言語 (Changes immediately upon saving)",
        friendly: "Include Friendly Mobs\n[Help] Targets passive mobs (animals, villagers, etc.) for combos and ascension.",
        plugin: "Enable System\n[Help] Turns the entire addon on or off.",
        ascend: "Ascension & Explosion\n[Help] Mobs will launch into the sky and explode when killed.",
        comboTitle: "Combo Titles\n[Help] Shows screen titles when comboing.",
        shake: "Camera Shake\n[Help] Shakes the screen during high combos.",
        effect: "VFX & SFX (Lightning, Sirens, Fireworks)\n[Help] Enables extreme effects like fireworks, sirens, and lightning.",
        magic: "Grant Ultimate Magic at 30 Combos\n[Help] (Default: OFF) Receive an apocalyptic magic item at 30 kills.",
        save: "§a[Overkill Party] Settings saved!§r",
        lore: ["Right-click/Hold to open settings.", "*Consumed on use, but returns if canceled.", "*Type '!overkill' in chat to get again."]
    };

    form.title(t.title);

    const addDropdown = (label, options, defaultIndex) => {
        try { form.dropdown(label, options, { defaultValueIndex: defaultIndex }); }
        catch (e) { form.dropdown(label, options, defaultIndex); }
    };
    
    const addToggle = (label, defaultVal) => {
        try { form.toggle(label, { defaultValue: defaultVal }); }
        catch (e) { form.toggle(label, defaultVal); }
    };

    addDropdown(t.lang, ["English", "日本語"], isJapanese ? 1 : 0);
    addToggle(t.friendly, isFriendlyOn);
    addToggle(t.plugin, isPluginOn);
    addToggle(t.ascend, isAscendOn);
    addToggle(t.comboTitle, isTitleOn);
    addToggle(t.shake, isShakeOn);
    addToggle(t.effect, isEffectOn);
    addToggle(t.magic, isMagicOn); 

    form.show(player).then(response => {
        if (response.canceled) {
            try {
                const inventory = player.getComponent("minecraft:inventory").container;
                if (inventory) {
                    const book = new ItemStack("minecraft:book", 1);
                    book.nameTag = isJapanese ? "§dOverkill設定本(使い捨て)§r" : "§dOverkill Settings Book§r";
                    book.setLore(t.lore);
                    inventory.addItem(book);
                }
            } catch (e) {}
            return;
        }

        const [langIndex, friendly, plugin, ascend, title, shake, effect, magic] = response.formValues;
        const currentLangIsJa = player.hasTag("overkill_lang_ja");
        const newLangIsJa = langIndex === 1;

        if (newLangIsJa) player.addTag("overkill_lang_ja"); else player.removeTag("overkill_lang_ja");

        if (friendly) player.removeTag("overkill_friendly_off"); else player.addTag("overkill_friendly_off");
        if (plugin) player.removeTag("overkill_off"); else player.addTag("overkill_off");
        if (ascend) player.removeTag("overkill_ascend_off"); else player.addTag("overkill_ascend_off");
        if (title) player.removeTag("overkill_title_off"); else player.addTag("overkill_title_off");
        if (shake) player.removeTag("overkill_shake_off"); else player.addTag("overkill_shake_off");
        if (effect) player.removeTag("overkill_effect_off"); else player.addTag("overkill_effect_off");
        if (magic) player.removeTag("overkill_magic_off"); else player.addTag("overkill_magic_off");
        
        if (currentLangIsJa !== newLangIsJa) {
            system.run(() => { showSettingsUI(player); });
        } else {
            player.sendMessage(newLangIsJa ? "§a[Overkill Party] 設定を保存しました。§r" : "§a[Overkill Party] Settings saved!§r");
        }
    }).catch(e => {});
}

// 超絶雷魔法のチャージ処理 (5秒間)
function castUltimateMagic(player) {
    player.addTag("overkill_charging");
    const isJa = player.hasTag("overkill_lang_ja");
    player.sendMessage(isJa ? "§d[魔法] 超絶チャージ開始...！！§r" : "§d[Magic] Ultimate Charge Initiated...!!§r");
    
    // 安全のため使用中は無敵・鈍足化
    try { player.addEffect("resistance", 100, { amplifier: 255, showParticles: false }); } catch(e){}
    try { player.addEffect("slowness", 100, { amplifier: 5, showParticles: false }); } catch(e){}

    let ticks = 0;
    const chargeInterval = system.runInterval(() => {
        let loc;
        try {
            loc = player.location;
        } catch (e) {
            system.clearRun(chargeInterval);
            try { player.removeTag("overkill_charging"); } catch(err){}
            return;
        }
        
        ticks++;
        const dim = player.dimension;

        // 音のチャージ (徐々にピッチが高くなる)
        if (ticks % 5 === 0) {
            try { dim.playSound("note.chime", loc, { pitch: 0.5 + (ticks / 50), volume: 3.0 }); } catch(e){}
        }
        if (ticks === 1) {
            try { dim.playSound("beacon.activate", loc, { volume: 5.0 }); } catch(e){}
            try { dim.playSound("portal.travel", loc, { volume: 2.0 }); } catch(e){}
        }

        // 螺旋状に集束するパーティクル
        if (!player.hasTag("overkill_effect_off")) {
            const angle1 = ticks * 0.5;
            const angle2 = angle1 + Math.PI;
            const radius = Math.max(0, 5 - (ticks * 0.05)); // 徐々に狭まる
            const yOffset = (ticks % 20) * 0.1; // 足元から頭へ
            
            try { dim.spawnParticle("minecraft:endrod", { x: loc.x + Math.cos(angle1)*radius, y: loc.y + yOffset, z: loc.z + Math.sin(angle1)*radius }); } catch(e){}
            try { dim.spawnParticle("minecraft:endrod", { x: loc.x + Math.cos(angle2)*radius, y: loc.y + yOffset, z: loc.z + Math.sin(angle2)*radius }); } catch(e){}
        }

        // 終盤の暗転とガタガタ
        if (ticks > 60) {
            if (ticks % 10 === 0 && !player.hasTag("overkill_shake_off")) {
                try { player.runCommand(`camerashake add @s 0.5 0.5 positional`); } catch(e){}
            }
            if (!player.hasTag("overkill_effect_off")) {
                try { dim.spawnParticle("minecraft:totem_particle", { x: loc.x + (Math.random()*4-2), y: loc.y + Math.random()*2, z: loc.z + (Math.random()*4-2) }); } catch(e){}
            }
        }
        
        // 発射直前のドラゴン咆哮
        if (ticks === 80) {
            if (!player.hasTag("overkill_effect_off")) {
                try { player.addEffect("darkness", 40, { showParticles: false }); } catch(e){}
            }
            try { dim.playSound("mob.enderdragon.growl", loc, { volume: 5.0 }); } catch(e){}
        }

        // 100ティック (5秒) で発射！
        if (ticks >= 100) {
            system.clearRun(chargeInterval);
            player.removeTag("overkill_charging");
            executeUltimateMagic(player);
        }
    }, 1);
}

// 【大改修】超絶雷魔法の発射処理 (範囲拡大・無差別爆撃の追加)
function executeUltimateMagic(player) {
    const loc = player.location;
    const dim = player.dimension;
    const isFriendlyOff = player.hasTag("overkill_friendly_off");

    // 中心部の大爆発音と強烈な画面揺れ
    try { dim.playSound("ambient.weather.lightning.impact", loc, { volume: 10.0, pitch: 0.8 }); } catch(e){}
    try { dim.playSound("random.explode", loc, { volume: 10.0 }); } catch(e){}
    try { dim.playSound("beacon.deactivate", loc, { volume: 5.0 }); } catch(e){}
    
    if (!player.hasTag("overkill_shake_off")) {
        try { player.runCommand("camerashake add @s 3.0 4.0 positional"); } catch(e){}
    }

    // 中心から放たれる衝撃波パーティクル
    if (!player.hasTag("overkill_effect_off")) {
        for (let i = 0; i < 8; i++) {
            const angle = (Math.PI / 4) * i;
            const pLoc = { x: loc.x + Math.cos(angle)*3, y: loc.y + 1, z: loc.z + Math.sin(angle)*3 };
            try { dim.spawnParticle("minecraft:sonic_explosion", pLoc); } catch(e){}
        }
    }

    // 1. 周囲50mのエンティティを取得して直撃させる
    let targets = [];
    try { targets = dim.getEntities({ location: loc, maxDistance: 50 }); } catch(e){}

    let hitCount = 0;

    targets.forEach(entity => {
        try {
            if (entity.id === player.id) return; // 自身は除外
            if (entity.typeId === "minecraft:item" || entity.typeId === "minecraft:xp_orb") return;
            if (entity.hasTag("overkill_dummy")) return;
            
            // 友好Mob設定がオフなら敵対Mobのみを対象にする
            if (isFriendlyOff) {
                const familyComp = entity.getComponent("minecraft:type_family");
                if (!familyComp || (!familyComp.hasTypeFamily("monster") && !familyComp.hasTypeFamily("slime"))) {
                    return;
                }
            }
            
            const eLoc = entity.location;
            
            // ターゲットの頭上に雷を落とし、爆発パーティクルを出す
            if (!player.hasTag("overkill_effect_off")) {
                try { dim.spawnEntity("minecraft:lightning_bolt", { x: eLoc.x, y: eLoc.y + 6, z: eLoc.z }); } catch(e){}
                try { dim.spawnParticle("minecraft:huge_explosion_emitter", eLoc); } catch(e){}
            }
            try { dim.playSound("ambient.weather.lightning.impact", eLoc, { volume: 5.0 }); } catch(e){}

            const health = entity.getComponent("minecraft:health");
            if (health) {
                entity.applyDamage(1000, {
                    cause: "lightning",
                    damagingEntity: player
                });
                hitCount++;
            }
        } catch(e){}
    });

    // 2. モブがいない場所にも無差別に雷を降らせる (プレイヤーの近く半径10mを除外した 10m〜50mのドーナツ状範囲)
    if (!player.hasTag("overkill_effect_off")) {
        const randomStrikes = 50; // 50発の無差別落雷
        for (let i = 0; i < randomStrikes; i++) {
            // 時間差で落とすことで視覚的な派手さを強調
            system.runTimeout(() => {
                const angle = Math.random() * Math.PI * 2;
                const distance = 10 + Math.random() * 40; // 10〜50の距離
                const strikeLoc = {
                    x: loc.x + Math.cos(angle) * distance,
                    y: loc.y, 
                    z: loc.z + Math.sin(angle) * distance
                };
                
                try { dim.spawnEntity("minecraft:lightning_bolt", { x: strikeLoc.x, y: strikeLoc.y + 6, z: strikeLoc.z }); } catch(e){}
                try { dim.playSound("ambient.weather.lightning.impact", strikeLoc, { volume: 3.0 }); } catch(e){}
                try { dim.spawnParticle("minecraft:huge_explosion_emitter", strikeLoc); } catch(e){}
                try { dim.spawnParticle("minecraft:lava_particle", strikeLoc); } catch(e){}
            }, i * 2); // 2ティック(0.1秒)ごとに1発ずつ
        }
    }

    const isJa = player.hasTag("overkill_lang_ja");
    player.sendMessage(isJa ? `§b[魔法] 究極雷撃が広範囲を焦土と化し、${hitCount} 体のモブを消し炭にしました！§r` : `§b[Magic] Ultimate Lightning scorched the area and turned ${hitCount} mobs to dust!§r`);
}

// エンティティキルイベント
world.afterEvents.entityDie.subscribe((event) => {
    const { deadEntity, damageSource } = event;

    try {
        if (!deadEntity || deadEntity.typeId === "minecraft:player") return;
        if (deadEntity.nameTag === "§cAscending...§r") return;
    } catch (e) { return; }

    const killer = damageSource.damagingEntity;

    if (!killer || killer.typeId !== "minecraft:player") return;
    if (killer.hasTag("overkill_off")) return;

    if (killer.hasTag("overkill_friendly_off")) {
        let isMonster = false;
        try {
            const familyComp = deadEntity.getComponent("minecraft:type_family");
            if (familyComp && (familyComp.hasTypeFamily("monster") || familyComp.hasTypeFamily("slime"))) {
                isMonster = true;
            }
        } catch (e) {}
        if (!isMonster) return; 
    }

    handleCombo(killer);

    if (killer.hasTag("overkill_ascend_off")) return;
    if (currentAscendingMobs >= MAX_ASCENDING_MOBS) return;

    let dimension, location, typeId, isBaby = false; 
    try {
        dimension = deadEntity.dimension;
        location = deadEntity.location;
        typeId = deadEntity.typeId;
        if (deadEntity.hasComponent("minecraft:is_baby")) isBaby = true;
    } catch (e) { return; }

    currentAscendingMobs++;

    try {
        const dummy = dimension.spawnEntity(typeId, location);
        dummy.nameTag = "§cAscending...§r"; 
        dummy.addTag("overkill_dummy");
        
        if (isBaby) {
            try { dummy.triggerEvent("minecraft:entity_born"); } catch(e) {}
            try { dummy.triggerEvent("minecraft:as_baby"); } catch(e) {}
        }

        system.runTimeout(() => {
            currentAscendingMobs--;
            if (dummy) {
                let explLocation;
                try { explLocation = dummy.location; } catch (e) {}

                if (explLocation) {
                    try { dimension.playSound("random.explode", explLocation); } catch(e) {}
                    try { dimension.playSound("firework.large_blast", explLocation); } catch(e) {}
                    try { dimension.playSound("firework.twinkle", explLocation); } catch(e) {}
                    try { dimension.spawnParticle("minecraft:huge_explosion_emitter", explLocation); } catch(e) {}
                    try { dimension.spawnParticle("minecraft:totem_particle", explLocation); } catch(e) {}
                    try { dimension.spawnParticle("minecraft:lava_particle", explLocation); } catch(e) {}
                    try { dimension.spawnParticle("minecraft:villager_happy", explLocation); } catch(e) {}
                }
                try { dummy.remove(); } catch(e) { try { dummy.teleport({ x: 0, y: -100, z: 0 }); } catch(e2) {} }
            }
        }, 20);

        system.runTimeout(() => {
            if (!dummy) return;
            try {
                const currentLoc = dummy.location;
                try {
                    dimension.playSound("firework.launch", currentLoc);
                    dimension.spawnParticle("minecraft:basic_flame_particle", currentLoc);
                } catch(e) {}
                try {
                    dummy.addEffect("levitation", 20, { amplifier: 20, showParticles: false });
                    dummy.addEffect("resistance", 20, { amplifier: 255, showParticles: false });
                } catch(e) {}
                try {
                    const dirX = Math.random() * 0.2 - 0.1;
                    const dirZ = Math.random() * 0.2 - 0.1;
                    dummy.applyKnockback(dirX, dirZ, 0.5, 3.0);
                } catch(e) {}
            } catch(e) {}
        }, 1);

    } catch (e) {
        currentAscendingMobs--;
    }
});

// 各種ヘルパー関数群
function fireComboFirework(player, offsetX, offsetY, offsetZ) {
    if (player.hasTag("overkill_effect_off")) return;
    try {
        const dim = player.dimension;
        const loc = player.location;
        const targetLoc = { x: loc.x + offsetX, y: loc.y + offsetY, z: loc.z + offsetZ };
        dim.playSound("firework.large_blast", targetLoc);
        dim.playSound("firework.twinkle", targetLoc);
        dim.spawnParticle("minecraft:huge_explosion_emitter", targetLoc);
        dim.spawnParticle("minecraft:totem_particle", targetLoc);
        dim.spawnParticle("minecraft:villager_happy", targetLoc);
    } catch (e) {}
}

function dropXpOrbs(player, count) {
    if (player.hasTag("overkill_effect_off")) return;
    try {
        const dim = player.dimension;
        const loc = player.location;
        for (let i = 0; i < count; i++) {
            const targetLoc = {
                x: loc.x + (Math.random() * 2 - 1),
                y: loc.y + 3 + (Math.random() * 2), 
                z: loc.z + (Math.random() * 2 - 1)
            };
            dim.spawnEntity("minecraft:xp_orb", targetLoc);
        }
    } catch(e) {}
}

function spawnSuperBlast(player, count) {
    if (player.hasTag("overkill_effect_off")) return;
    try {
        const dim = player.dimension;
        const loc = player.location;
        for (let i = 0; i < count; i++) {
            const angle = Math.random() * Math.PI * 2;
            const radius = 3 + Math.random() * 5; 
            const targetLoc = {
                x: loc.x + Math.cos(angle) * radius,
                y: loc.y, 
                z: loc.z + Math.sin(angle) * radius
            };
            const lightningLoc = { x: targetLoc.x, y: targetLoc.y + 6, z: targetLoc.z };
            try { dim.spawnEntity("minecraft:lightning_bolt", lightningLoc); } catch(e) {}
            try { dim.playSound("ambient.weather.lightning.impact", targetLoc, { volume: 5.0 }); } catch(e) {}
            try { dim.spawnParticle("minecraft:sonic_explosion", { x: targetLoc.x, y: targetLoc.y + 1, z: targetLoc.z }); } catch(e) {}
            try { dim.spawnParticle("minecraft:huge_explosion_emitter", targetLoc); } catch(e) {}
            try { dim.spawnParticle("minecraft:lava_particle", targetLoc); } catch(e) {}
        }
    } catch(e) {}
}

function spawnCarpetBombing(player, count) {
    if (player.hasTag("overkill_effect_off")) return;
    try {
        const dim = player.dimension;
        const loc = player.location;
        
        // 【変更】「号令(Call: horn.call.5)」の角笛のピッチをいじって空襲サイレン風の不協和音にする
        try { dim.playSound("horn.call.5", loc, { volume: 10.0, pitch: 0.5 }); } catch(e) {}
        try { dim.playSound("horn.call.5", loc, { volume: 10.0, pitch: 0.55 }); } catch(e) {}
        
        // サイレン特有の「ウーウー」感を出すために時間差でもう一度鳴らす
        system.runTimeout(() => {
            try { dim.playSound("horn.call.5", loc, { volume: 10.0, pitch: 0.5 }); } catch(e) {}
            try { dim.playSound("horn.call.5", loc, { volume: 10.0, pitch: 0.55 }); } catch(e) {}
        }, 60); // 3秒後
        
        for (let i = 0; i < count; i++) {
            system.runTimeout(() => {
                const targetLoc = {
                    x: loc.x + (Math.random() * 20 - 10),
                    y: loc.y, 
                    z: loc.z + (Math.random() * 20 - 10)
                };
                try { dim.playSound("random.explode", targetLoc, { volume: 4.0, pitch: 0.6 + Math.random() * 0.4 }); } catch(e) {}
                try { dim.spawnParticle("minecraft:huge_explosion_emitter", targetLoc); } catch(e) {}
                try { dim.spawnParticle("minecraft:camp_fire", targetLoc); } catch(e) {}
                if (!player.hasTag("overkill_shake_off")) {
                    try { player.runCommand(`camerashake add @s 0.3 0.5 positional`); } catch(e) {}
                }
            }, i * 5);
        }
    } catch(e) {}
}

// コンボ処理ロジック
function handleCombo(player) {
    const currentTick = system.currentTick;
    const COMBO_TIMEOUT = 200; 

    let comboData = playerCombos.get(player.id);

    if (comboData && (currentTick - comboData.lastTick) <= COMBO_TIMEOUT) {
        comboData.count++;
        comboData.lastTick = currentTick;
    } else {
        comboData = { count: 1, lastTick: currentTick };
    }
    playerCombos.set(player.id, comboData);

    const combo = comboData.count;

    const getOptions = (subtitleText) => {
        return { subtitle: subtitleText, fadeInDuration: 5, stayDuration: 40, fadeOutDuration: 10 };
    };
    const getRndNum = (range) => (Math.random() * range - (range / 2));

    const showTitle = !player.hasTag("overkill_title_off");
    const showShake = !player.hasTag("overkill_shake_off");
    const showEffect = !player.hasTag("overkill_effect_off");

    // 30コンボで超絶雷魔法アイテムを付与 (1回のみ)
    if (combo === 30 && !player.hasTag("overkill_magic_off")) {
        try {
            const inv = player.getComponent("minecraft:inventory").container;
            if (inv) {
                const isJa = player.hasTag("overkill_lang_ja");
                const magicItem = new ItemStack("minecraft:blaze_rod", 1);
                magicItem.nameTag = isJa ? MAGIC_NAME_JA : MAGIC_NAME_EN;
                magicItem.setLore(isJa ? [
                    "右クリック/長押しで5秒間チャージ後、",
                    "周囲50mを無差別に焦土と化す究極魔法。",
                    "※使い捨て"
                ] : [
                    "Right-click/Hold to charge for 5 seconds,",
                    "then unleash an apocalyptic storm within 50m.",
                    "*Single use"
                ]);
                inv.addItem(magicItem);
                
                if (showTitle) player.onScreenDisplay.setTitle("§dULTIMATE MAGIC!§r", getOptions("ITEM GRANTED!"));
                try { player.dimension.playSound("random.levelup", player.location, { volume: 5.0 }); } catch(e){}
            }
        } catch(e){}
    }

    switch (combo) {
        case 1: break;
        case 2:
            if (showTitle) player.onScreenDisplay.setTitle("§bDOUBLE KILL!", getOptions("BOOM!"));
            try { player.dimension.playSound("note.bassattack", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 0.2 0.5 positional"); } catch (e) {}
            break;
        case 3:
            if (showTitle) player.onScreenDisplay.setTitle("§gTRIPLE KILL!", getOptions("BOOM!!"));
            try { player.dimension.playSound("note.pling", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 0.4 1.0 positional"); } catch (e) {}
            dropXpOrbs(player, 5);
            break;
        case 4:
            if (showTitle) player.onScreenDisplay.setTitle("§cQUADRA KILL!", getOptions("BOOM!!!"));
            try { player.dimension.playSound("note.bell", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 0.6 1.5 positional"); } catch (e) {}
            dropXpOrbs(player, 8);
            fireComboFirework(player, 0, 2, 0);
            break;
        case 5:
            if (showTitle) player.onScreenDisplay.setTitle("§5PENTA KILL!", getOptions("INSANE!"));
            try { player.dimension.playSound("ambient.weather.thunder", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 0.8 1.5 positional"); } catch (e) {}
            dropXpOrbs(player, 12);
            fireComboFirework(player, 1, 2, 0);
            fireComboFirework(player, -1, 2, 0);
            spawnSuperBlast(player, 1);
            break;
        case 6:
            if (showTitle) player.onScreenDisplay.setTitle("§4MONSTER KILL!", getOptions("CRAZY!"));
            try { player.dimension.playSound("horn.call.0", player.location, { volume: 5.0 }); } catch (e) {}
            if (showEffect) try { player.dimension.spawnParticle("minecraft:totem_particle", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 1.0 2.0 positional"); } catch (e) {}
            dropXpOrbs(player, 15);
            fireComboFirework(player, 1, 2, 0);
            fireComboFirework(player, -1, 2, 0);
            fireComboFirework(player, 0, 2, 1);
            spawnSuperBlast(player, 2);
            break;
        case 7:
            if (showTitle) player.onScreenDisplay.setTitle("§6RAMPAGE!", getOptions("OUT OF CONTROL!"));
            try { player.dimension.playSound("horn.call.1", player.location, { volume: 5.0 }); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 1.2 2.0 positional"); } catch (e) {}
            dropXpOrbs(player, 20);
            fireComboFirework(player, 2, 2, 0);
            fireComboFirework(player, -2, 2, 0);
            fireComboFirework(player, 0, 2, 2);
            fireComboFirework(player, 0, 2, -2);
            spawnSuperBlast(player, 3);
            break;
        case 8:
            if (showTitle) player.onScreenDisplay.setTitle("§cDOMINATING!", getOptions("UNSTOPPABLE!"));
            // 8コンボ目も号令(horn.call.5)をアレンジした音に変更
            try { player.dimension.playSound("horn.call.5", player.location, { volume: 5.0, pitch: 1.0 }); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 1.5 2.5 positional"); } catch (e) {}
            dropXpOrbs(player, 25);
            fireComboFirework(player, 1, 2, 1);
            fireComboFirework(player, -1, 2, -1);
            fireComboFirework(player, 1, 2, -1);
            fireComboFirework(player, -1, 2, 1);
            spawnCarpetBombing(player, 5); 
            break;
        case 9:
            if (showTitle) player.onScreenDisplay.setTitle("§eGODLIKE!", getOptions("UNBELIEVABLE!"));
            try { player.dimension.playSound("mob.enderdragon.growl", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 1.8 2.5 positional"); } catch (e) {}
            if (showEffect) try { player.addEffect("darkness", 40, { showParticles: false }); } catch(e) {}
            dropXpOrbs(player, 30);
            for(let i=0; i<6; i++) { fireComboFirework(player, getRndNum(4), 2, getRndNum(4)); }
            spawnSuperBlast(player, 7);
            break;
        case 10:
            if (showTitle) player.onScreenDisplay.setTitle("§bLEGENDARY!", getOptions("BEYOND GODLIKE!"));
            try { player.dimension.playSound("mob.wither.spawn", player.location); } catch (e) {}
            if (showShake) try { player.runCommand("camerashake add @s 2.5 3.0 positional"); } catch (e) {}
            if (showEffect) {
                try { player.addEffect("darkness", 60, { showParticles: false }); } catch(e) {}
                try { player.addEffect("night_vision", 60, { showParticles: false }); } catch(e) {}
            }
            dropXpOrbs(player, 40);
            for(let i=0; i<10; i++) { fireComboFirework(player, getRndNum(6), 2, getRndNum(6)); }
            spawnSuperBlast(player, 10);
            break;
        default:
            if (combo > 10) {
                if (showTitle) player.onScreenDisplay.setTitle("§4OVERKILL!", getOptions(`${combo} COMBO!`));
                
                const variation = Math.floor(Math.random() * 5);
                
                if (variation === 0) {
                    try { player.dimension.playSound("mob.enderdragon.growl", player.location); } catch (e) {}
                    if (showShake) try { player.runCommand("camerashake add @s 2.0 2.0 positional"); } catch (e) {}
                    dropXpOrbs(player, 25);
                    for(let i=0; i<3; i++) { fireComboFirework(player, getRndNum(4), 2, getRndNum(4)); }
                    spawnSuperBlast(player, 5);
                } else if (variation === 1) {
                    try { player.dimension.playSound("mob.wither.spawn", player.location); } catch (e) {}
                    if (showShake) try { player.runCommand("camerashake add @s 2.5 3.0 positional"); } catch (e) {}
                    if (showEffect) try { player.addEffect("darkness", 40, { showParticles: false }); } catch(e) {}
                    dropXpOrbs(player, 25);
                    for(let i=0; i<2; i++) { fireComboFirework(player, getRndNum(6), 2, getRndNum(6)); }
                    spawnSuperBlast(player, 8);
                } else if (variation === 2) {
                    try { player.dimension.playSound("random.levelup", player.location, { volume: 5.0 }); } catch (e) {}
                    try { player.dimension.playSound("firework.twinkle", player.location, { volume: 5.0 }); } catch (e) {}
                    if (showShake) try { player.runCommand("camerashake add @s 1.5 2.0 positional"); } catch (e) {}
                    if (showEffect) try { player.dimension.spawnParticle("minecraft:totem_particle", player.location); } catch (e) {}
                    dropXpOrbs(player, 40); 
                    for(let i=0; i<8; i++) { fireComboFirework(player, getRndNum(8), 2, getRndNum(8)); }
                    spawnSuperBlast(player, 2);
                } else if (variation === 3) {
                    try { player.dimension.playSound("mob.wither.spawn", player.location); } catch (e) {}
                    if (showShake) try { player.runCommand("camerashake add @s 2.5 3.0 positional"); } catch (e) {}
                    if (showEffect) {
                        try { player.addEffect("darkness", 60, { showParticles: false }); } catch(e) {}
                        try { player.addEffect("night_vision", 60, { showParticles: false }); } catch(e) {}
                    }
                    dropXpOrbs(player, 40);
                    for(let i=0; i<10; i++) { fireComboFirework(player, getRndNum(6), 2, getRndNum(6)); }
                    spawnSuperBlast(player, 10);
                } else {
                    if (showEffect) try { player.addEffect("darkness", 30, { showParticles: false }); } catch(e) {}
                    dropXpOrbs(player, 30);
                    spawnCarpetBombing(player, 15);
                }
            }
            break;
    }
}

// メモリリーク防止：プレイヤーがサーバーを抜けた際にコンボデータを削除
world.afterEvents.playerLeave.subscribe((event) => {
    playerCombos.delete(event.playerId);
    // 退室時にもタグを剥がしておく
    try { event.player.removeTag("overkill_charging"); } catch(e){}
});