import { world, system, EntityDamageCause, Player, ItemStack, EquipmentSlot, BlockPermutation, GameMode } from "@minecraft/server";
import { ActionFormData, ModalFormData, MessageFormData } from "@minecraft/server-ui";

// --- Constants & Config ---
const BEDROCK_ROOM_LOC = { x: 0, y: 100, z: 0 }; 
const PENALTY_SECONDS = 180; 
const ITEM_FLINT = "minecraft:flint_and_steel";
const ITEM_LOG = "minecraft:oak_log";
const ITEM_BREAD = "minecraft:bread";
const ITEM_START = "minecraft:clock"; 
const ITEM_DEBUG = "minecraft:book"; 

// Game Modes
const MODE = {
    CHOICE: 0,
    RANDOM: 1,
    SPEEDRUN: 2
};

// Radar Helper (Fixed)
function updateRadar(player, targetTypeIds, name) {
    const data = getPlayerData(player);
    if (!player.dimension || player.dimension.id !== "minecraft:nether") {
        data.radarMessages.push(`§7${name}: Nether Only`);
        return;
    }

    try {
        const options = {
            location: player.location,
            maxDistance: 128
        };
        const allEntities = player.dimension.getEntities(options);
        
        let targetEntity = null;
        let minDistanceSq = Infinity;

        for (const entity of allEntities) {
            if (targetTypeIds.includes(entity.typeId)) {
                const dx = entity.location.x - player.location.x;
                const dy = entity.location.y - player.location.y;
                const dz = entity.location.z - player.location.z;
                const distSq = dx * dx + dy * dy + dz * dz;
                
                if (distSq < minDistanceSq) {
                    minDistanceSq = distSq;
                    targetEntity = entity;
                }
            }
        }

        if (targetEntity) {
            const dx = targetEntity.location.x - player.location.x;
            const dz = targetEntity.location.z - player.location.z;
            const dist = Math.floor(Math.sqrt(dx * dx + dz * dz));
            
            // Angle Calculation
            let playerYaw = player.getRotation().y; 
            const rad = (playerYaw + 90) * Math.PI / 180;
            const dirX = Math.cos(rad);
            const dirZ = Math.sin(rad);
            const len = Math.sqrt(dx*dx + dz*dz);
            let tDirX = 0;
            let tDirZ = 0;
            if (len > 0) {
                 tDirX = dx / len;
                 tDirZ = dz / len;
            }

            const dot = dirX * tDirX + dirZ * tDirZ;
            const cross = dirX * tDirZ - dirZ * tDirX;

            let dirStr = "";
            if (dot > 0.5) dirStr = "↑"; // Forward
            else if (dot < -0.5) dirStr = "↓"; // Backward
            else if (cross > 0) dirStr = "→"; // Right
            else dirStr = "←"; // Left

            data.radarMessages.push(`${name}: §e${dirStr} §f${dist}m`);
        } else {
            data.radarMessages.push(`§7${name}: No signal (128m)`);
        }
    } catch (e) {}
}

// Perks Definition
const PERKS = [
    {
        id: "piglin_friend",
        name: "§6Piglin Friend",
        desc: "Respawn with full Golden Armor",
        tier: 1,
    },
    {
        id: "hasty_miner",
        name: "§eHasty Miner",
        desc: "Permanent Haste II",
        tier: 1,
        onTick: (player) => player.addEffect("haste", 40, { amplifier: 1, showParticles: false })
    },
    {
        id: "night_owl",
        name: "§9Night Owl",
        desc: "Permanent Night Vision",
        tier: 1,
        onTick: (player) => player.addEffect("night_vision", 400, { showParticles: false })
    },
    {
        id: "chef_choice",
        name: "§6Chef's Choice",
        desc: "Respawn with 16 Golden Carrots",
        tier: 1,
    },
    {
        id: "fire_proof",
        name: "§cFire Proof",
        desc: "Permanent Fire Resistance",
        tier: 2,
        onTick: (player) => player.addEffect("fire_resistance", 40, { showParticles: false })
    },
    {
        id: "no_fall",
        name: "§bNo Fall",
        desc: "Permanent Slow Falling (No Fall Damage)",
        tier: 2,
        onTick: (player) => player.addEffect("slow_falling", 40, { showParticles: false })
    },
    {
        id: "super_jump",
        name: "§aSuper Jump",
        desc: "Permanent Jump Boost II",
        tier: 2,
        onTick: (player) => player.addEffect("jump_boost", 40, { amplifier: 1, showParticles: false })
    },
    {
        id: "water_kid",
        name: "§3Water Kid",
        desc: "Permanent Water Breathing & Conduit Power",
        tier: 2,
        onTick: (player) => {
            player.addEffect("water_breathing", 40, { showParticles: false });
            player.addEffect("conduit_power", 40, { showParticles: false });
        }
    },
    {
        id: "speedster",
        name: "§bSpeedster",
        desc: "Permanent Speed V",
        tier: 3,
        onTick: (player) => player.addEffect("speed", 40, { amplifier: 4, showParticles: false })
    },
    {
        id: "hulk_smash",
        name: "§4Hulk Smash",
        desc: "Permanent Strength II",
        tier: 3,
        onTick: (player) => player.addEffect("strength", 40, { amplifier: 1, showParticles: false })
    },
    {
        id: "iron_stomach",
        name: "§6Iron Stomach",
        desc: "Permanent Saturation (No Hunger)",
        tier: 3,
        onTick: (player) => player.addEffect("saturation", 40, { amplifier: 0, showParticles: false })
    },
    {
        id: "wolverine",
        name: "§dRegeneration",
        desc: "Permanent Regeneration",
        tier: 3,
        onTick: (player) => player.addEffect("regeneration", 40, { amplifier: 0, showParticles: false })
    },
    {
        id: "fortress_radar",
        name: "§cFortress Radar",
        desc: "Detects nearby Nether Fortress enemies",
        tier: 3,
        onTick: (player) => {
            updateRadar(player, ["minecraft:blaze", "minecraft:wither_skeleton"], "§cFortress");
        }
    },
    {
        id: "bastion_radar",
        name: "§6Bastion Radar",
        desc: "Detects nearby Bastion Remnant enemies",
        tier: 3,
        onTick: (player) => {
            updateRadar(player, ["minecraft:piglin_brute"], "§6Bastion");
        }
    },
    {
        id: "ender_gift",
        name: "§5Enderman's Gift",
        desc: "Respawn with 4 Ender Pearls",
        tier: 4,
    },
    {
        id: "blaze_gift",
        name: "§6Blaze's Gift",
        desc: "Respawn with 2 Blaze Rods",
        tier: 4,
    },
    {
        id: "vampire",
        name: "§4Vampire",
        desc: "Heal HP upon killing enemies",
        tier: 4,
    },
    {
        id: "explosive_punch",
        name: "§cExplosive Punch",
        desc: "Attacks cause explosions",
        tier: 4,
    },
    {
        id: "walking_bomb",
        name: "§c§kWalking Bomb",
        desc: "Explode every 3s (No terrain damage)",
        tier: 99,
        isRandomOnly: true,
        isTemporary: true,
        onTick: (player) => {
            if (system.currentTick % 60 === 0) {
                player.dimension.createExplosion(player.location, 2, { breaksBlocks: false, source: player });
            }
        }
    },
    {
        id: "rocket_man",
        name: "§c§kRocket Man",
        desc: "Permanent Levitation (Float away)",
        tier: 99,
        isRandomOnly: true,
        isTemporary: true,
        onTick: (player) => player.addEffect("levitation", 40, { amplifier: 0, showParticles: false })
    },
    {
        id: "snail_curse",
        name: "§c§kSnail Curse",
        desc: "Permanent Slowness VI (Can barely move)",
        tier: 99,
        isRandomOnly: true,
        isTemporary: true,
        onTick: (player) => player.addEffect("slowness", 40, { amplifier: 5, showParticles: false })
    },
    {
        id: "blind_bat",
        name: "§c§kBlind Bat",
        desc: "Permanent Blindness",
        tier: 99,
        isRandomOnly: true,
        isTemporary: true,
        onTick: (player) => player.addEffect("blindness", 40, { showParticles: false })
    }
];

// --- Global Variables ---
let gameState = {
    isRunning: false,
    startTime: 0,
    penaltyTime: 0, 
    mode: MODE.CHOICE
};
let isSetupDone = false; 

// Maps
const playerData = new Map(); 
const lookingUpMap = new Map();

function getPlayerData(player) {
    if (!playerData.has(player.name)) {
        playerData.set(player.name, { perks: [], isDead: false, radarMessages: [] });
    }
    const data = playerData.get(player.name);
    if (!data.radarMessages) data.radarMessages = [];
    return data;
}

// Helper: Safe Run Timeout
function safeRunTimeout(callback, ticks) {
    if (typeof system.runTimeout === 'function') {
        system.runTimeout(callback, ticks);
    } else {
        let counter = 0;
        const interval = system.runInterval(() => {
            counter++;
            if (counter >= ticks) {
                system.clearRun(interval);
                callback();
            }
        }, 1);
    }
}

// Helper: Get Dimension Safe
function getOverworldDimension() {
    try {
        const dim = world.getDimension("overworld");
        if (dim) return dim;
    } catch {}
    try {
        const dim = world.getDimension("minecraft:overworld");
        if (dim) return dim;
    } catch {}
    return null;
}

// Helper: Run Command Safely
function runCommand(player, command) {
    const dim = player?.dimension || getOverworldDimension();

    if (dim && typeof dim.runCommandAsync === 'function') {
        dim.runCommandAsync(command).catch(e => {
            runCommandFallback(player, dim, command);
        });
        return;
    }
    if (dim && typeof dim.runCommand === 'function') {
        try {
            dim.runCommand(command);
            return;
        } catch (e) {}
    }
    runCommandFallback(player, dim, command);
}

function runCommandFallback(player, dim, command) {
    if (player && typeof player.runCommandAsync === 'function') {
        player.runCommandAsync(command).catch(e => {});
        return;
    }
    if (player && typeof player.runCommand === 'function') {
        try { player.runCommand(command); return; } catch (e) {}
    }
}

// Helper: Teleport Spectator to Random Player
function teleportToRandomPlayer(spectator) {
    try {
        const players = world.getAllPlayers();
        const targets = players.filter(p => p.id !== spectator.id && p.hasTag("challenger"));

        if (targets.length > 0) {
            const target = targets[Math.floor(Math.random() * targets.length)];
            spectator.teleport(target.location, { dimension: target.dimension });
            spectator.sendMessage(`§a[System] Teleported to ${target.name}.`);
        } else {
            spectator.sendMessage("§c[System] No valid players (Challengers) found.");
        }
    } catch (e) {}
}

// --- Initialization & Item Distribution ---

function giveLobbyItems(player) {
    try {
        const inventory = player.getComponent("inventory").container;
        let hasStartItem = false;

        for (let i = 0; i < inventory.size; i++) {
            const item = inventory.getItem(i);
            if (!item) continue;
            
            if (item.typeId === ITEM_START) hasStartItem = true;
            if (item.typeId === ITEM_FLINT || item.typeId === ITEM_LOG || item.typeId === ITEM_BREAD) {
                inventory.setItem(i, undefined);
            }
        }

        const allPlayers = world.getAllPlayers();
        let hostExists = allPlayers.some(p => p.hasTag("host"));

        if (!hostExists) {
            player.addTag("host");
            player.sendMessage("§eYou are now the Host player.");
        }

        if (player.hasTag("host") && !hasStartItem) {
            const clock = new ItemStack(ITEM_START, 1);
            clock.nameTag = "§aGame Menu";
            inventory.addItem(clock);
            player.sendMessage("§eUse the 'Game Menu (Clock)' to control the game.");
        }

    } catch (e) {}
}

function giveGameItems(player) {
    try {
        const inventory = player.getComponent("inventory").container;
        const equipment = player.getComponent("equippable");
        const data = getPlayerData(player);
        const perks = data.perks;

        for (let i = 0; i < inventory.size; i++) {
            const item = inventory.getItem(i);
            if (item && item.typeId === ITEM_START) {
                inventory.setItem(i, undefined);
            }
        }

        let hasFlint = false;
        for(let i=0; i<inventory.size; i++) {
            if(inventory.getItem(i)?.typeId === ITEM_FLINT) hasFlint = true;
        }
        if (!hasFlint) inventory.addItem(new ItemStack(ITEM_FLINT, 1));

        if (gameState.mode !== MODE.SPEEDRUN) {
            let hasLog = false;
            let hasBread = false;
            for(let i=0; i<inventory.size; i++) {
                const item = inventory.getItem(i);
                if(!item) continue;
                if(item.typeId === ITEM_LOG) hasLog = true;
                if(item.typeId === ITEM_BREAD) hasBread = true;
            }
            if (!hasLog) inventory.addItem(new ItemStack(ITEM_LOG, 5));
            if (!hasBread) inventory.addItem(new ItemStack(ITEM_BREAD, 16));
        }

        // Perk Items logic 
        if (perks.includes("piglin_friend") && equipment) {
            const head = equipment.getEquipment(EquipmentSlot.Head);
            if (!head) equipment.setEquipment(EquipmentSlot.Head, new ItemStack("minecraft:golden_helmet"));
            const chest = equipment.getEquipment(EquipmentSlot.Chest);
            if (!chest) equipment.setEquipment(EquipmentSlot.Chest, new ItemStack("minecraft:golden_chestplate"));
            const legs = equipment.getEquipment(EquipmentSlot.Legs);
            if (!legs) equipment.setEquipment(EquipmentSlot.Legs, new ItemStack("minecraft:golden_leggings"));
            const feet = equipment.getEquipment(EquipmentSlot.Feet);
            if (!feet) equipment.setEquipment(EquipmentSlot.Feet, new ItemStack("minecraft:golden_boots"));
        }
        
        let hasGoldenCarrot = false;
        let hasEnderPearl = false;
        let hasBlazeRod = false;
        for(let i=0; i<inventory.size; i++) {
            const item = inventory.getItem(i);
            if(!item) continue;
            if (item.typeId === "minecraft:golden_carrot") hasGoldenCarrot = true;
            if (item.typeId === "minecraft:ender_pearl") hasEnderPearl = true;
            if (item.typeId === "minecraft:blaze_rod") hasBlazeRod = true;
        }

        if (perks.includes("chef_choice") && !hasGoldenCarrot) inventory.addItem(new ItemStack("minecraft:golden_carrot", 16));
        if (perks.includes("ender_gift") && !hasEnderPearl) inventory.addItem(new ItemStack("minecraft:ender_pearl", 4));
        if (perks.includes("blaze_gift") && !hasBlazeRod) inventory.addItem(new ItemStack("minecraft:blaze_rod", 2));

    } catch(e) {}
}

// --- Event: Player Spawn ---
world.afterEvents.playerSpawn.subscribe((event) => {
    const { player } = event;

    safeRunTimeout(() => {
        if (gameState.isRunning) {
            if (player.hasTag("challenger")) {
                runCommand(player, `execute as @a[name="${player.name}"] run gamemode survival @s`);
                return;
            }
            // Late Joiner
            runCommand(player, `execute as @a[name="${player.name}"] run gamemode spectator @s`);
            player.sendMessage("§c§lGame in progress. You are a Spectator.");
            player.sendMessage("§e[Tip] Look straight UP to teleport to a random player!");
            
            // Try initial teleport
            teleportToRandomPlayer(player);
            return;
        }

        if (isSetupDone) {
            try {
                const tpLoc = { ...BEDROCK_ROOM_LOC, y: BEDROCK_ROOM_LOC.y + 1 };
                player.teleport(tpLoc);
                runCommand(player, `execute as @a[name="${player.name}"] run gamemode survival @s`);
                giveLobbyItems(player); 
            } catch (e) {}
        }
    }, 10);
});

// --- Event: Item Use (MENU) ---
world.afterEvents.itemUse.subscribe((event) => {
    const { source: player, itemStack } = event;
    
    // Host Menu (Clock)
    if (itemStack.typeId === ITEM_START) {
        showHostMenu(player);
    }
});

// --- Host Menu ---
async function showHostMenu(player) {
    // Only Host can see full menu
    if (!player.hasTag("host")) {
        player.sendMessage("§cOnly the Host can use this menu.");
        return;
    }

    const form = new ActionFormData()
        .title("Nether Speedrun - Host Menu")
        .body("Control Panel")
        .button("Start Game", "textures/items/diamond_sword")
        .button("Reset Game & Setup", "textures/ui/refresh");

    try {
        const response = await form.show(player);
        if (response.canceled) return;

        if (response.selection === 0) {
            if (gameState.isRunning) {
                player.sendMessage("§cGame is already running.");
            } else {
                showModeSelection(player);
            }
        } else if (response.selection === 1) {
            // Reset
            gameState = { isRunning: false, startTime: 0, penaltyTime: 0, mode: MODE.CHOICE };
            playerData.clear();
            runCommand(player, "gamerule falldamage true");
            
            (async () => {
                await setupBedrockRoom(player);
                for(const p of world.getAllPlayers()) {
                        p.removeTag("challenger");
                        runCommand(p, `execute as @a[name="${p.name}"] run gamemode survival @s`);
                        const tpLoc = { ...BEDROCK_ROOM_LOC, y: BEDROCK_ROOM_LOC.y + 1 };
                        p.teleport(tpLoc);
                        giveLobbyItems(p);
                        p.sendMessage("§eGame has been reset by Host.");
                }
            })();
        }
    } catch (e) {}
}

// Mode Selection (Sub Menu)
async function showModeSelection(player) {
    const form = new ActionFormData()
        .title("Select Mode")
        .body("Choose a game mode to start.")
        .button("Choice Mode", "textures/items/diamond")
        .button("Random Mode", "textures/items/gold_nugget")
        .button("Speedrun Mode", "textures/items/diamond_boots");

    const response = await form.show(player);
    if (response.canceled) return;

    gameState.mode = response.selection;
    gameState.isRunning = true;
    gameState.startTime = Date.now();
    gameState.penaltyTime = 0;
    
    world.sendMessage(`§l§aGame Start! Mode: ${["Choice", "Random", "Speedrun"][gameState.mode]}`);
    world.sendMessage("Enter the Nether Portal and survive the return from The End!");
    
    for (const p of world.getAllPlayers()) {
        p.addTag("challenger");
        giveGameItems(p);
    }
}

// Perk Selection UI (Death)
async function showPerkSelection(player) {
    const data = getPlayerData(player);
    const availablePerks = PERKS.filter(p => !data.perks.includes(p.id) && !p.isRandomOnly);
    
    if (availablePerks.length === 0) {
        player.sendMessage("§eNo more perks available!");
        return;
    }
    const choices = availablePerks.sort(() => 0.5 - Math.random()).slice(0, 3);

    const form = new ActionFormData()
        .title("You Died! Choose a Perk")
        .body(`Death Penalty: +${PENALTY_SECONDS}s\nChoose a perk to come back stronger.`);

    choices.forEach(perk => {
        // Show Name AND Description
        form.button(`${perk.name}\n${perk.desc}`);
    });

    try {
        const response = await form.show(player);
        if (response.canceled) {
            const randomPerk = choices[0];
            addPerk(player, randomPerk.id);
            return;
        }
        const selectedPerk = choices[response.selection];
        addPerk(player, selectedPerk.id);
    } catch (e) {
        console.warn("Error showing perk selection:", e);
    }
}

function addPerk(player, perkId) {
    const data = getPlayerData(player);
    if (!data.perks.includes(perkId)) {
        data.perks.push(perkId);
        const perk = PERKS.find(p => p.id === perkId);
        if(perk) {
            player.sendMessage(`§l§aPerk Acquired: ${perk.name}`);
            player.sendMessage(`§7Effect: ${perk.desc}`);
            if (perk.onAcquire) {
                try { perk.onAcquire(player); } catch (e) {}
            }
        }
    }
    giveGameItems(player);
}

// --- Setup Bedrock Room ---
async function setupBedrockRoom(player = null) {
    const dim = getOverworldDimension();
    if (!dim) return;

    try {
        runCommand(player, "tickingarea remove bedrock_room");
        runCommand(player, `tickingarea add circle ${BEDROCK_ROOM_LOC.x} ${BEDROCK_ROOM_LOC.y} ${BEDROCK_ROOM_LOC.z} 2 bedrock_room`);
        
        await new Promise(resolve => safeRunTimeout(resolve, 20));
    } catch (e) {}

    for (let i = 0; i < 2; i++) {
        try {
            for (let x = -3; x <= 3; x++) {
                for (let y = 0; y <= 6; y++) {
                    for (let z = -3; z <= 3; z++) {
                        const loc = { x: BEDROCK_ROOM_LOC.x + x, y: BEDROCK_ROOM_LOC.y + y, z: BEDROCK_ROOM_LOC.z + z };
                        try {
                            const block = dim.getBlock(loc);
                            if (block) {
                                if (x === -3 || x === 3 || y === 0 || y === 6 || z === -3) {
                                    if (x === 0 && y === 6 && z === 0) {
                                         block.setPermutation(BlockPermutation.resolve("minecraft:bedrock"));
                                    } else {
                                         block.setPermutation(BlockPermutation.resolve("minecraft:bedrock"));
                                    }
                                } else if (z === 3) {
                                    block.setPermutation(BlockPermutation.resolve("minecraft:bedrock")); 
                                } else {
                                     if (x === 0 && y === 5 && z === 0) {
                                        block.setPermutation(BlockPermutation.resolve("minecraft:light_block", { "block_light_level": 15 }));
                                     } else {
                                        block.setPermutation(BlockPermutation.resolve("minecraft:air"));
                                     }
                                }
                            }
                        } catch (err) {}
                    }
                }
            }
            const obsidianLocs = [];
            for (let x = -2; x <= 2; x++) {
                obsidianLocs.push({x: x, y: 1, z: 3});
                obsidianLocs.push({x: x, y: 6, z: 3});
            }
            for (let y = 2; y <= 5; y++) {
                obsidianLocs.push({x: -2, y: y, z: 3});
                obsidianLocs.push({x: 2, y: y, z: 3});
            }
            for (const pos of obsidianLocs) {
                const loc = { x: BEDROCK_ROOM_LOC.x + pos.x, y: BEDROCK_ROOM_LOC.y + pos.y, z: BEDROCK_ROOM_LOC.z + pos.z };
                dim.getBlock(loc)?.setPermutation(BlockPermutation.resolve("minecraft:obsidian"));
            }
            for (let x = -1; x <= 1; x++) {
                for (let y = 2; y <= 5; y++) {
                    const loc = { x: BEDROCK_ROOM_LOC.x + x, y: BEDROCK_ROOM_LOC.y + y, z: BEDROCK_ROOM_LOC.z + 3 };
                    dim.getBlock(loc)?.setPermutation(BlockPermutation.resolve("minecraft:air"));
                }
            }
            for (let x = -3; x <= 3; x++) {
                for (let y = 0; y <= 6; y++) {
                    for (let zOffset = 1; zOffset <= 3; zOffset++) {
                        const loc = { x: BEDROCK_ROOM_LOC.x + x, y: BEDROCK_ROOM_LOC.y + y, z: BEDROCK_ROOM_LOC.z + 3 + zOffset };
                        dim.getBlock(loc)?.setPermutation(BlockPermutation.resolve("minecraft:bedrock"));
                    }
                }
            }
        } catch (e) {}
        
        await new Promise(resolve => safeRunTimeout(resolve, 10));
    }
}

// --- Main Loop ---
system.runInterval(() => {
    // Auto Setup
    if (!isSetupDone) {
        const players = world.getAllPlayers();
        if (players.length > 0) {
            isSetupDone = true;
            (async () => {
                await setupBedrockRoom(players[0]);
                for (const p of players) {
                    try {
                        const tpLoc = { ...BEDROCK_ROOM_LOC, y: BEDROCK_ROOM_LOC.y + 1 };
                        p.teleport(tpLoc);
                        p.sendMessage("§aWelcome to Nether Speedrun!");
                        giveLobbyItems(p); 
                    } catch (e) {}
                }
            })();
        }
    }

    if (gameState.isRunning) {
        const now = Date.now();
        const elapsedSeconds = Math.floor((now - gameState.startTime) / 1000) + gameState.penaltyTime;
        const h = Math.floor(elapsedSeconds / 3600);
        const m = Math.floor((elapsedSeconds % 3600) / 60);
        const s = elapsedSeconds % 60;
        const timeStr = `${h > 0 ? h + ':' : ''}${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;

        for (const player of world.getAllPlayers()) {
            // Check Spectator Teleport (Look Up)
            if (!player.hasTag("challenger")) {
                const rotation = player.getRotation();
                // -85 is almost straight up
                const isLookingUp = rotation.x < -85;
                
                if (isLookingUp && !lookingUpMap.get(player.id)) {
                    teleportToRandomPlayer(player);
                }
                lookingUpMap.set(player.id, isLookingUp);
            }

            if (player.hasTag("challenger")) {
                const data = getPlayerData(player);
                let currentHp = 20;
                try {
                    const healthComp = player.getComponent("minecraft:health");
                    if (healthComp) currentHp = healthComp.currentValue;
                } catch (e) {}

                // Death
                if (currentHp <= 0 && !data.isDead) {
                    data.isDead = true;
                    gameState.penaltyTime += PENALTY_SECONDS;
                    world.sendMessage(`§c§lDEATH! §rPenalty +${PENALTY_SECONDS}s`);
                    
                    const originalPerkCount = data.perks.length;
                    data.perks = data.perks.filter(perkId => {
                        const perkDef = PERKS.find(p => p.id === perkId);
                        return !perkDef || !perkDef.isTemporary;
                    });
                    if (data.perks.length < originalPerkCount) {
                        player.sendMessage("§eChaos skills cleansed.");
                    }
                }

                // Respawn
                if (currentHp > 0 && data.isDead) {
                    data.isDead = false;
                    try { 
                        const tpLoc = { ...BEDROCK_ROOM_LOC, y: BEDROCK_ROOM_LOC.y + 1 };
                        player.teleport(tpLoc); 
                    } catch(e){}

                    if (gameState.mode === MODE.CHOICE) {
                        safeRunTimeout(() => { showPerkSelection(player).catch(console.error); }, 20);
                    } else if (gameState.mode === MODE.RANDOM) {
                        const availablePerks = PERKS.filter(p => !data.perks.includes(p.id));
                        const isOnlyDebuffsLeft = availablePerks.every(p => p.isRandomOnly);
                        if (availablePerks.length > 0 && !isOnlyDebuffsLeft) {
                            const randomPerk = availablePerks[Math.floor(Math.random() * availablePerks.length)];
                            addPerk(player, randomPerk.id);
                        } else {
                            player.sendMessage("§eYou have learned all useful perks!");
                        }
                    } else {
                        player.sendMessage("§cSpeedrun Mode: No Pain, No Gain.");
                    }
                    giveGameItems(player);
                }

                // Action Bar
                let actionBarMsg = `§l§6Time: ${timeStr} §r(Deaths: ${Math.floor(gameState.penaltyTime / PENALTY_SECONDS)})`;
                if (data.radarMessages && data.radarMessages.length > 0) {
                    actionBarMsg += "\n" + data.radarMessages.join("  ");
                }

                try {
                    player.onScreenDisplay.setActionBar(actionBarMsg);
                } catch(e) {}
                
                data.radarMessages = [];

                data.perks.forEach(perkId => {
                    const perk = PERKS.find(p => p.id === perkId);
                    if (perk && perk.onTick) {
                        try { perk.onTick(player); } catch(e) {}
                    }
                });
            }
        }
    }
}, 1);

// Event Processing
world.afterEvents.playerDimensionChange.subscribe((event) => {
    if (!gameState.isRunning) return;
    const { player, fromDimension, toDimension } = event;
    // Check if challenger
    if (!player.hasTag("challenger")) return;

    const data = getPlayerData(player);
    if (data.isDead) return;
    if (fromDimension.id === "minecraft:the_end" && toDimension.id === "minecraft:overworld") {
        finishGame(player);
    }
});

function finishGame(winner) {
    gameState.isRunning = false;
    const now = Date.now();
    const elapsedSeconds = Math.floor((now - gameState.startTime) / 1000) + gameState.penaltyTime;
    const h = Math.floor(elapsedSeconds / 3600);
    const m = Math.floor((elapsedSeconds % 3600) / 60);
    const s = elapsedSeconds % 60;
    const timeStr = `${h > 0 ? h + ':' : ''}${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
    
    const modeName = ["Choice", "Random", "Speedrun"][gameState.mode];
    const deathCount = Math.floor(gameState.penaltyTime / PENALTY_SECONDS);

    world.sendMessage(`§e========================================`);
    world.sendMessage(`§6§l🎉 CONGRATULATIONS! 🎉`);
    world.sendMessage(`§bWinner: §f${winner.name}`);
    world.sendMessage(`§dMode: §f${modeName}`);
    world.sendMessage(`§aTime: §l${timeStr}`);
    world.sendMessage(`§cDeaths: §f${deathCount}`);
    world.sendMessage(`§e========================================`);
    
    for (const p of world.getAllPlayers()) {
        try {
            if (p.onScreenDisplay) {
                p.onScreenDisplay.setTitle(`§6§l=== VICTORY! ===`);
                p.onScreenDisplay.setSubtitle(`§7[${modeName}]§r\n§aTime: ${timeStr} §cDeaths: ${deathCount}`);
            }
            runCommand(p, "playsound random.totem @s");
        } catch(e) { }
    }

    const celebrate = (count) => {
        if (count > 10) return; 
        for (const p of world.getAllPlayers()) {
            try {
                if (p.dimension) {
                    const rx = (Math.random() - 0.5) * 4;
                    const rz = (Math.random() - 0.5) * 4;
                    runCommand(p, `summon minecraft:fireworks_rocket ~${rx.toFixed(1)} ~2 ~${rz.toFixed(1)}`);
                    runCommand(p, "playsound random.levelup @s");
                }
            } catch(e) {}
        }
        safeRunTimeout(() => celebrate(count + 1), 20);
    };
    celebrate(0);
}