import { world, system, SystemAfterEvents, TicksPerSecond } from "@minecraft/server"
world.afterEvents.itemUse.subscribe(data => {
    const player = data.source
    const item = data.itemStack
    const dimension = player.dimension.id
    if (item.typeId === "minecraft:stick") {
        const block = player.getBlockFromViewDirection({ maxDistance: 45 }).block
        player.teleport({ x: block.location.x, y: block.location.y + 1, z: block.location.z }, { checkForBlocks: true })
    }
    if (item.typeId === "minecraft:lava_bucket") {
        world.getDimension(dimension).spawnEntity("minecraft:chicken", player.location)
    }
    if (item.typeId === "minecraft:water_bucket") {
        world.getDimension(dimension).spawnEntity("minecraft:chicken", player.location)
    }
    if (item.typeId === "minecraft:powder_snow_bucket") {
        world.getDimension(dimension).spawnEntity("minecraft:chicken", player.location)
    }
}
)
world.beforeEvents.playerBreakBlock.subscribe(event => {
    const player = event.player
    const block = event.block
    const blockunderid = block.below(1).typeId
    const blockunder = block.below(1)
    if (!blockunder?.hasTag("diamond_pick_diggable") && !blockunder?.hasTag("iron_pick_diggable") && !blockunder?.hasTag("metal") && blockunder?.typeId != "minecraft:diamond_block" && !player.isSneaking || (blockunder?.typeId == "minecraft:iron_bars" && !player.isSneaking)) {
        player.runCommandAsync(`setblock ${block.location.x} ${block.location.y} ${block.location.z} ${blockunderid}`)
    }
}
)
world.afterEvents.playerPlaceBlock.subscribe(event => {
    const player = event.player
    const block = event.block
    const blockid = event.block.typeId
    let chance = Math.random()
    let blockchance = Math.random()
    if (!block.hasTag("diamond_pick_diggable") && !block.hasTag("iron_pick_diggable") && !block.hasTag("metal") && block.typeId != "minecraft:diamond_block" && !player.isSneaking && chance <= 0.4) {
        player.runCommandAsync(`setblock ${block.above(1).location.x} ${block.above(1).location.y} ${block.above(1).location.z} ${blockid}`)
    }
    if (!player.isSneaking && chance >= 0.6 && blockchance >= 0.6) {
        player.applyKnockback(chance + 0.5, chance + 0.5, chance + 0.5, chance + 0.5)
    }
    if (!player.isSneaking && chance >= 0.6 && blockchance <= 0.4) {
        player.applyKnockback((chance + 0.2) * -1, (chance + 0.2) * -1, (chance + 0.2) * -1, (chance + 0.2) * -1)
    }
})
world.afterEvents.entityDie.subscribe(event => {
    const entity = event.deadEntity
    const source = event.damageSource.damagingEntity

    if (source?.typeId === "minecraft:player" && entity.typeId != "minecraft:item" && entity.typeId != "minecraft:splash_potion") {
        const block = entity?.dimension?.getBlock({ x: entity.location.x, y: entity.location.y - 10, z: entity.location.z })
        if (!block?.isAir && !block?.hasTag("diamond_pick_diggable") && !block?.hasTag("iron_pick_diggable") && !block?.hasTag("metal") && block?.typeId != "minecraft:diamond_block") {
            entity.runCommandAsync(`setblock ${entity.location.x} ${entity.location.y} ${entity.location.z} ${block.typeId}`)
        }
    }
}
)
world.afterEvents.buttonPush.subscribe(event => {
    let player = event.source
    let button = event.block
    let dimension = event.block.dimension.id
    const entityquery = { excludeTypes: player, closest: true, location: button.location }
    if (player.typeId === "minecraft:player" && player.typeId != "minecraft:item") {
        for (let entity of world.getDimension(dimension).getEntities(entityquery)) {
            if (entity.typeId != "minecraft:player") {
                button.dimension.spawnEntity(entity.typeId, button.location)
                break
            }
        }
    }
}
)
world.afterEvents.projectileHitBlock.subscribe(event => {
    const blockhitlocation = event.location
    const entity = event.source
    const block = entity?.dimension?.getBlock({ x: blockhitlocation.x, y: blockhitlocation.y - 20, z: blockhitlocation.z })
    if (!block?.isAir && !block?.hasTag("diamond_pick_diggable") && !block?.hasTag("iron_pick_diggable") && !block?.hasTag("metal") && block?.typeId != "minecraft:diamond_block") {
        entity?.runCommandAsync(`setblock ${block?.location.x} ${block?.location.y + 22} ${block?.location.z} ${block?.typeId}`)
    }
})
//explosion with no block breaking activates when using a piston
world.afterEvents.pistonActivate.subscribe(event => {
    const piston = event.piston
    piston.block.dimension.createExplosion(piston.block.location, 1, { source: piston, causesFire: true, breaksBlocks: false })
})
world.afterEvents.playerDimensionChange.subscribe(event => {
    const prevlocation = event.fromLocation
    const nextlocation = event.toLocation
    const player = event.player
    const prevblock = player.dimension.getBlock({ x: prevlocation.x, y: prevlocation.y - 10, z: prevlocation.z })
    const nextblock = player.dimension.getBlock({ x: nextlocation.x, y: nextlocation.y - 10, z: nextlocation.z })
    if (!prevblock?.isAir) {
        player.runCommandAsync(`setblock ${prevlocation.x} ${prevlocation.y + 10} ${prevlocation.z} ${prevblock?.typeId}`)
    }
    if (!nextblock?.isAir) {
        player.runCommandAsync(`setblock ${nextlocation.x} ${nextlocation.y + 10} ${nextlocation.z} ${nextblock?.typeId}`)
    }
})
world.afterEvents.weatherChange.subscribe(() => {
    for (const player of world.getAllPlayers()) {
        player.runCommandAsync(`summon minecraft:creeper ~~10~ 0 0 minecraft:become_charged`)
        break
    }
})
world.beforeEvents.entityRemove.subscribe(event => {
    const entity = event.removedEntity
    let chance = Math.random()
    for (let player of world.getAllPlayers()) {
        if (entity.typeId != "minecraft:falling_block" && entity.typeId != "minecraft:player" && entity.typeId != "minecraft:item" && chance >= 0.9 && entity.typeId != "minecraft:zombie_villager_v2" && entity.typeId != "minecraft:fireball") {
            player.runCommandAsync(`summon ${entity.typeId} ${player.location.x + 10} ${player.location.y + 10} ${player.location.z + 10}`)
            break
        }
    }
})

world.afterEvents.projectileHitEntity.subscribe(event => {
    try {
        const entity = event.source
        if (entity?.typeId != "minecraft:player") {
            entity.setOnFire(1, false)
        }
        if (entity?.typeId === "minecraft:player") {
            entity.applyKnockback(Math.random(), Math.random(), Math.random(), Math.random())
        }
    } catch { }
})
world.afterEvents.entitySpawn.subscribe(event => {
    try {
        let chance = Math.random()
        const entity = event.entity
        if (entity.typeId != "minecraft:item" && entity.typeId != "minecraft:player" && chance >= 0.6 && entity.typeId !== "minecraft:fireball" && entity.typeId != "omni_science:creeper_dj") {
            entity.applyImpulse({ x: Math.random() + 0.5, y: Math.random() + 0.5, z: Math.random() + 0.5 })
        }
    } catch { }
})
system.runInterval(() => {
    for (let player of world.getAllPlayers()) {
        for (let entity of world.getDimension(player.dimension.id).getEntities({ location: player.location, excludeTypes: player, maxDistance: 25 })) {
            let chance = Math.random()
            if (entity.typeId != "minecraft:player" && chance >= 0.2 && entity.typeId != "minecraft:item" && entity.typeId != "omni_science:creeper_dj") {
                if (chance >= 0.5) {
                    entity.applyImpulse({ x: Math.random() + 0.5, y: Math.random() + 0.1, z: Math.random() + 0.5 })
                } else {
                    entity.applyImpulse({ x: (Math.random() + 0.5) * -1, y: Math.random() + 0.1, z: (Math.random() + 0.5) * -1 })
                }

            }
            if (entity.typeId != "minecraft:player" && chance >= 0 && entity.typeId === "minecraft:item" && entity.typeId != "omni_science:creeper_dj") {
                if (chance >= 0.5) {
                    entity.applyImpulse({ x: Math.random() + 0.5, y: Math.random() + 0.5, z: Math.random() + 0.5 })
                } else {
                    entity.applyImpulse({ x: (Math.random() + 0.5) * -1, y: Math.random() + 0.5, z: (Math.random() + 0.5) * -1 })
                    break
                }
            }
        }
    }
}, 100);
system.runInterval(() => {
    world.getAllPlayers().filter(
        (data) => {
            const chance = Math.random()
            if (data?.typeId === 'minecraft:player' && data?.isSwimming && chance >= 0.3) {
                data.applyKnockback(0, 0, 0, 5)
                data.playSound('bubble.upinside', data.location)
            }
        }
    )
}, 200)
system.runInterval(() => {
    world.getAllPlayers().filter(
        (data) => {
            const chance = Math.random()
            const { x, y, z } = data.location
            if (chance < 0.15) {
                if (chance <= 1 / 4) {
                    data.dimension.spawnEntity('minecraft:lightning_bolt', { x: x + 20, y: y, z: z + 20 })
                }
                if (chance <= 2 / 4) {
                    data.dimension.spawnEntity('minecraft:lightning_bolt', { x: x - 20, y: y, z: z - 20 })
                }
                if (chance <= 3 / 4) {
                    data.dimension.spawnEntity('minecraft:lightning_bolt', { x: x + 20, y: y, z: z - 20 })
                }
                else {
                    data.dimension.spawnEntity('minecraft:lightning_bolt', { x: x - 20, y: y, z: z + 20 })
                }
            }
        }
    )
}, 400)
system.runInterval(() => {
    world.getDimension('overworld').getEntities({ type: 'minecraft:lightning_bolt' }).filter(
        (event) => {
            const { x, y, z } = event.location
            const chance = Math.random()
            if (event.dimension.getBlock({ x: x, y: y - 1, z: z }) && chance > 0.75) {
                event.dimension.createExplosion({ x: x, y: y - 1, z: z }, 10, { allowUnderwater: true, breaksBlocks: true, causesFire: true })
            }
        }
    )
}, 20)
world.afterEvents.entityDie.subscribe(event => {
    try {
        const entity = event.deadEntity
        const source = event.damageSource
        const chance = Math.random()
        const { x, y, z } = entity?.location
        if (entity?.typeId === 'minecraft:zombie' && chance < 0.4 && source?.damagingEntity?.typeId === 'minecraft:player') {
            entity.dimension.spawnEntity('omni_science:zombie_meteor', { x: x, y: 256, z: z })
        }
    } catch { }
})

world.afterEvents.itemCompleteUse.subscribe(event => {
    const foodItem = event.itemStack.hasTag('minecraft:is_food')
    const source = event.source
    const chance = Math.random()
    if (foodItem) {
        if (chance <= 1 / 36) {
            source.addEffect('absorption', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 2 / 36) {
            source.addEffect('bad_omen', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 3 / 36) {
            source.addEffect('blindness', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 4 / 36) {
            source.addEffect('conduit_power', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 5 / 36) {
            source.addEffect('darkness', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 6 / 36) {
            source.addEffect('fatal_poison', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 7 / 36) {
            source.addEffect('fire_resistance', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 8 / 36) {
            source.addEffect('haste', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 9 / 36) {
            source.addEffect('health_boost', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 10 / 36) {
            source.addEffect('village_hero', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 11 / 36) {
            source.addEffect('hunger', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 12 / 36) {
            source.addEffect('infested', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 13 / 36) {
            source.addEffect('instant_damage', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 14 / 36) {
            source.addEffect('instant_health', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 15 / 36) {
            source.addEffect('invisibility', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 16 / 36) {
            source.addEffect('jump_boost', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 17 / 36) {
            source.addEffect('levitation', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 18 / 36) {
            source.addEffect('mining_fatigue', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 19 / 36) {
            source.addEffect('nausea', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 20 / 36) {
            source.addEffect('night_vision', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 21 / 36) {
            source.addEffect('oozing', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 22 / 36) {
            source.addEffect('poison', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 23 / 36) {
            source.addEffect('raid_omen', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 24 / 36) {
            source.addEffect('regeneration', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 25 / 36) {
            source.addEffect('resistance', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 26 / 36) {
            source.addEffect('saturation', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 27 / 36) {
            source.addEffect('slow_falling', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 28 / 36) {
            source.addEffect('slowness', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 29 / 36) {
            source.addEffect('speed', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 30 / 36) {
            source.addEffect('strength', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 31 / 36) {
            source.addEffect('trial_omen', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 32 / 36) {
            source.addEffect('water_breathing', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 33 / 36) {
            source.addEffect('weakness', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 34 / 36) {
            source.addEffect('weaving', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 35 / 36) {
            source.addEffect('wind_charged', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }
        else if (chance <= 36 / 36) {
            source.addEffect('wither', TicksPerSecond * 10, { showParticles: true, amplifier: 5 });
        }

    }
})
world.beforeEvents.worldInitialize.subscribe(event => {
    event.itemComponentRegistry.registerCustomComponent('omni_science:bagel', {
        onConsume({ source }) {
            //source.runCommand(`playsound item.bagel @a[r=256] ~~~ 10 1`)
            source.dimension.playSound("item.bagel", source.location, { volume: 1, pitch: 1 })
        }
    })
})

//projectiles randomly spawn stuff
system.runInterval(() => {
    world.getDimension('overworld').getEntities().forEach(
        (data) => {
            const projectile = data?.hasComponent('projectile')
            const chance = Math.random()
            if (projectile && chance < 0.1 && projectile.typeId !== "minecraft:fireball" && projectile.typeId !== "minecraft:trident") {
                try {
                    if (chance <= 1 / 2 && projectile.typeId !== "minecraft:fireball" && projectile.typeId !== "minecraft:trident") {
                        data.dimension.spawnEntity('tnt', data.location)
                    }
                    else if (chance <= 2 / 2) {
                        data.dimension.spawnEntity('lightning_bolt', data.location)
                    }
                } catch { }
            }
        }
    )
}, 1)
system.runInterval(() => {
    world.getDimension('nether').getEntities().forEach(
        (data) => {
            const projectile = data?.hasComponent('projectile')
            const chance = Math.random()
            if (projectile && chance < 0.1 && projectile.typeId !== "minecraft:fireball" && projectile.typeId !== "minecraft:trident") {
                try {
                    if (chance <= 1 / 2 && projectile.typeId !== "minecraft:fireball" && projectile.typeId !== "minecraft:trident") {
                        data.dimension.spawnEntity('tnt', data.location)
                    }
                    else if (chance <= 2 / 2) {
                        data.dimension.spawnEntity('lightning_bolt', data.location)
                    }
                } catch { }
            }
        }
    )
}, 1)
system.runInterval(() => {
    world.getDimension('the_end').getEntities().forEach(
        (data) => {
            const projectile = data?.hasComponent('projectile')
            const chance = Math.random()
            if (projectile && chance < 0.1 && projectile.typeId !== "minecraft:fireball" && projectile.typeId !== "minecraft:trident") {
                try {
                    if (chance <= 1 / 2) {
                        data.dimension.spawnEntity('tnt', data.location)
                    }
                    else if (chance <= 2 / 2) {
                        data.dimension.spawnEntity('lightning_bolt', data.location)
                    }
                } catch { }
            }
        }
    )
}, 1)

//when player hits a block, player can get crazy haste for a couple of seconds
world.afterEvents.entityHitBlock.subscribe(event => {
    const player = event.damagingEntity.typeId === 'minecraft:player'
    const entity = event.damagingEntity
    const chance = Math.random()
    if (player && chance < 0.09) {
        entity.addEffect('haste', TicksPerSecond * 2, { showParticles: false, amplifier: 255 })
    }
})
//knockback stick
world.afterEvents.entityHitEntity.subscribe(event => {
    const target = event.hitEntity
    const playerWithStick = event.damagingEntity?.getComponent('equippable')?.getEquipment('Mainhand')?.typeId === 'omni_science:knockback_stick'
    const damager = event.damagingEntity
    if (playerWithStick) {
        target.applyKnockback(damager.getViewDirection().x, damager.getViewDirection().z, 40, 0)
    }
})
