import { EntityComponentTypes, ItemStack, system, world } from "@minecraft/server"
import { ActionFormData } from "@minecraft/server-ui"

system.runInterval(() => {
  const playerList = world.getAllPlayers();

  for (let player of playerList) {
    if (player.hasComponent(EntityComponentTypes.Riding)) {
      const entity = player.getComponent(EntityComponentTypes.Riding).entityRidingOn
      
      if (entity.typeId == "lua_mp:water_dolphin" && entity.hasComponent(EntityComponentTypes.IsTamed)) {
        player.addEffect("water_breathing", 20, { showParticles: false })

        entity.addEffect("water_breathing", 20, { showParticles: false })

        const playerXMovement = Math.abs(player.getVelocity().x)
        const playerZMovement = Math.abs(player.getVelocity().z)
        let playerYDirection = player.getViewDirection().y

        if (playerYDirection > 1) {
          playerYDirection = 1
        } else if (playerYDirection < -1) {
          playerYDirection = -1
        }

        if (Math.abs(entity.getVelocity().x) + Math.abs(entity.getVelocity().z) > 0.6) {
          try {
            entity.applyImpulse({
              x: 0,
              y: playerYDirection / ((playerXMovement + playerZMovement) * 20),
              z: 0
            })
          } catch {
          }
        }
      }

      else if (entity.typeId == "lua_mp:moonlight_tiger" && entity.hasComponent(EntityComponentTypes.IsTamed)) {
        player.addEffect("night_vision", 209, { showParticles: false })
      }
    }
  }
}, 1)

world.afterEvents.entitySpawn.subscribe((eventData) => {
  if (eventData.entity.typeId.startsWith("lua_mp:") && eventData.entity.typeId != "lua_mp:trader") {
    try {
      let customName = eventData.entity.typeId.split(":")[1].replace("_", " ").split(" ").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" ")
      eventData.entity.nameTag = customName
    } catch { }
  }
})

world.afterEvents.entityDie.subscribe((eventData) => {
  if (eventData.deadEntity.typeId == "lua_mp:sky_phoenix") {
    try { eventData.deadEntity.runCommand("fill ~-8~-8~-8 ~8~8~8 air replace light_block_15") } catch { }
  }
})

world.afterEvents.dataDrivenEntityTrigger.subscribe((eventData) => {
  switch (eventData.eventId) {
    case "minecraft:log_beaver_drop_item":
      let item = ["minecraft:oak_log", "minecraft:spruce_log", "minecraft:birch_log", "minecraft:jungle_log", "minecraft:acacia_log", "minecraft:dark_oak_log", "minecraft:crimson_stem", "minecraft:warped_stem", "minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:apple", "minecraft:stick"]
      let randomAmount = 0
      if (Math.floor(Math.random() * 100) + 1 <= 75) {
        randomAmount = Math.floor(Math.random() * 5) + 2
      } else {
        randomAmount = Math.floor(Math.random() * 6) + 6
      }
      let randomItem = item[Math.floor(Math.random() * item.length)]

      eventData.entity.dimension.spawnItem(new ItemStack(randomItem, randomAmount), eventData.entity.location)
      break
    case "minecraft:netherite_beetle_drop_item":
      eventData.entity.dimension.spawnItem(new ItemStack("minecraft:ancient_debris", 1), eventData.entity.location)
      break
    case "minecraft:diamond_dragon_drop_item":
      eventData.entity.dimension.spawnItem(new ItemStack(
        ["minecraft:diamond", "minecraft:emerald", "minecraft:gold_ingot"][Math.floor(Math.random() * 3)],
        Math.ceil(Math.random() * 3)
      ), eventData.entity.location)
      break
      
  }
})

world.afterEvents.entityHealthChanged.subscribe((eventData) => {
  try {
    if (eventData.newValue <= 3 && eventData.newValue < eventData.oldValue) {
      eventData.entity.dimension.getEntities({
        type: "lua_mp:fiery_fox",
        location: eventData.entity.location,
        maxDistance: 30
      }).forEach((entity) => {
        try {
          const tc = entity.getComponent(EntityComponentTypes.Tameable)

          if (tc.isTamed) {
            if (tc.tamedToPlayer.name == eventData.entity.name) {
              let cd = entity.getDynamicProperty("cooldown")
              if (cd == undefined) cd = 0
              if (Date.now() - cd > 90000) {
                entity.setDynamicProperty("cooldown", Date.now())
                tc.tamedToPlayer.addEffect("instant_health", 20, {
                  amplifier: 255,
                  showParticles: false
                })
                for (let i = 0; i < 25; i++) {
                  let x = Math.random() * 3 - 1.5
                  let y = Math.random() * 3 - 0.5
                  let z = Math.random() * 3 - 1.5
                  eventData.entity.dimension.spawnParticle("minecraft:heart_particle", {
                    x: eventData.entity.location.x + x,
                    y: eventData.entity.location.y + y,
                    z: eventData.entity.location.z + z
                  })
                }
              }
            }
          }
        } catch { }
      })
    } 

    if (eventData.newValue < eventData.oldValue) {
      eventData.entity?.dimension.getEntities({
        type: "lua_mp:golden_antelope",
        location: eventData.entity.location,
        maxDistance: 30
      }).forEach((entity) => {
        try {
          const tc = entity.getComponent(EntityComponentTypes.Tameable)

          if (tc.isTamed) {
            if (tc.tamedToPlayer.name == eventData.entity.name) {
              let cd = entity.getDynamicProperty("cooldown")
              if (cd == undefined) cd = 0
              if (Date.now() - cd > 15000) {
                entity.setDynamicProperty("cooldown", Date.now())
                tc.tamedToPlayer.addEffect("regeneration", 100, {
                  amplifier: 1,
                  showParticles: false
                })
                for (let i = 0; i < 4; i++) {
                  let x = Math.random() * 3 - 1.5
                  let y = Math.random() * 3 - 0.5
                  let z = Math.random() * 3 - 1.5
                  eventData.entity.dimension.spawnParticle("minecraft:heart_particle", {
                    x: eventData.entity.location.x + x,
                    y: eventData.entity.location.y + y,
                    z: eventData.entity.location.z + z
                  })
                }
              }
            }
          }
        } catch { }
      })
    }
  } catch { }
})

world.afterEvents.entityHitEntity.subscribe((eventData) => {
  if (eventData.damagingEntity.typeId == "lua_mp:fire_beetle") {
    eventData.damagingEntity.addEffect("instant_health", 100, {
      amplifier: 255,
      showParticles: false
    })
    eventData.damagingEntity.dimension.createExplosion(eventData.damagingEntity.location, 4, {
      allowUnderwater: true,
      breaksBlocks: true,
      causesFire: true,
      source: eventData.damagingEntity.getComponent(EntityComponentTypes.Tameable).tamedToPlayer
    })
    system.runTimeout(() => {
      eventData.damagingEntity.kill()
    })
  }
})

system.runInterval(() => {
  for (let dimension of ["overworld", "nether", "the_end"]) {
    const dim = world.getDimension(dimension)
    
    dim.getEntities({
      type: "lua_mp:venom_scorpion"
    }).forEach((entity) => {
      let name = entity.getComponent(EntityComponentTypes.Tameable).tamedToPlayer?.name
      if (name) name = `name=!"${name}",r=4.5,rm=0.001,family=monster`
      else name = "r=4.5,rm=0.001,family=monster"
      entity.runCommand(`effect @e[${name}] fatal_poison 2 2 true`)
      entity.runCommand(`effect @e[${name.replace("monster", "player")}] fatal_poison 2 2 true`)
    })

  }
}, 40)

world.afterEvents.itemUse.subscribe((eventData) => {
  if (eventData.itemStack.typeId == "minecraft:red_dye") {
    let riding = eventData.source.getComponent(EntityComponentTypes.Riding)?.entityRidingOn
    if (riding?.typeId === "lua_mp:sky_phoenix") {
      riding.playAnimation("animation.sky_phoenix.fire")
      for (let i = 0; i < 4; i++) {
        system.runTimeout(() => {
          let vd = riding.getViewDirection()
          let x = Math.floor(vd.x * 5)
          let y = Math.floor(vd.y * 5)
          let z = Math.floor(vd.z * 5)
          let loc = {
            x: riding.location.x + x,
            y: riding.location.y + y,
            z: riding.location.z + z
          }
          riding.dimension.getEntities({
            location: loc,
            maxDistance: 5,
            families: ["monster"]
          }).forEach((target) => {
            target.setOnFire(8)
          })
          riding.dimension.getEntities({
            location: loc,
            maxDistance: 5,
            families: ["player"]
          }).forEach((target) => {
            target.setOnFire(8)
          })
        }, i * 10)
      } 
    }
  } else if (eventData.itemStack.typeId == "minecraft:light_blue_dye") {
    let riding = eventData.source.getComponent(EntityComponentTypes.Riding)?.entityRidingOn
    if (riding?.typeId === "lua_mp:thunder_gryphon") {
      let location = eventData.source.getBlockFromViewDirection()?.block.location
      if (location) {
        try {
          riding.dimension.spawnEntity("lightning_bolt", location)
        } catch {
          
        }
      }
    }
  }
})

system.runInterval(() => {
  for (let dimension of ["overworld", "nether", "the_end"]) {
    const dim = world.getDimension(dimension)

    dim.getEntities({
      type: "lua_mp:sky_phoenix"
    }).forEach((entity) => {
      let rc = entity.getComponent(EntityComponentTypes.Rideable)?.getRiders().length
      if (rc > 0) {
        if (Math.abs(entity.getVelocity().x) + Math.abs(entity.getVelocity().z) > 0.3) {
          entity.runCommand(`function lua/mythical_pets/flying_mob`)
        } else {
          entity.runCommand("effect @s slow_falling 1 0 true")
        }
      }
      entity.runCommand("fill ~-8~-8~-8 ~8~8~8 air replace light_block_15")
      entity.runCommand("fill ~~-1~ ~~1~ light_block_15 replace air")
    })

    dim.getEntities({
      type: "lua_mp:shadow_crow"
    }).forEach((entity) => {
      let rc = entity.getComponent(EntityComponentTypes.Rideable)?.getRiders()
      if (rc?.length > 0) {
        if (Math.abs(entity.getVelocity().x) + Math.abs(entity.getVelocity().z) > 0.3) {
          entity.runCommand(`function lua/mythical_pets/flying_mob`)
        } else {
          entity.runCommand("effect @s slow_falling 1 0 true")
        }

        let cooldown = entity.getDynamicProperty("invisible")
        if (!cooldown) {
          cooldown = Date.now() + Math.floor(Math.random() * 20000) + 20000 // 20s - 40s
          entity.setDynamicProperty("invisible", cooldown)
        }

        if (cooldown < Date.now()) {
          entity.addEffect("invisibility", 220, {
            showParticles: false
          })
          entity.addEffect("speed", 220, {
            showParticles: false,
            amplifier: 14
          })
          rc[0].addEffect("invisibility", 220, {
            showParticles: false 
          })
          
          entity.setDynamicProperty("invisible", Date.now() + Math.floor(Math.random() * 20000) + 20000) // 20s - 40s
        }
      }
    })

    dim.getEntities({
      type: "lua_mp:thunder_gryphon"
    }).forEach((entity) => {
      let rc = entity.getComponent(EntityComponentTypes.Rideable)?.getRiders().length
      if (rc > 0) {
        if (Math.abs(entity.getVelocity().x) + Math.abs(entity.getVelocity().z) > 0.3) {
          entity.runCommand(`function lua/mythical_pets/flying_mob`)
        } else {
          entity.runCommand("effect @s slow_falling 1 0 true")
        }
      }
    })
  }
}, 10)

world.afterEvents.playerSpawn.subscribe((eventData) => {
  if (eventData.player.hasTag("lua_mp:info_book")) return

  eventData.player.runCommand("give @s lua_mp:info_book")
  eventData.player.addTag("lua_mp:info_book")
})

world.afterEvents.itemCompleteUse.subscribe((eventData) => {
  if (eventData.itemStack.typeId == "lua_mp:info_book") {
    showInfoBook(eventData.source)
  }
})

function showInfoBook(player) {
  new ActionFormData()
    .title("Mythical Pets Information")
    .body("§dMythical Pets§r can be obtained either by buying them from the §6Pet Shop§r with emeralds or by finding them in the wild. \n\n§6Pet Shops§r can be found naturally throughout the world. Watch out! Some pets can harm each other!\n\n§eNote§r: To craft the Information Book or the Pet Shop, place a book, an oak plank, and a stick in your inventory and interact with a crafting table. You will then be able to see the recipes.\n\n§eInteract with the button to view more.§r")
    .button("Crystal Bunny", "textures/lua/mythical_pets/renders/crystal_bunny")
    .button("Diamond Dragon", "textures/lua/mythical_pets/renders/diamond_dragon")
    .button("Fiery Fox", "textures/lua/mythical_pets/renders/fiery_fox")
    .button("Fire Beetle", "textures/lua/mythical_pets/renders/fire_beetle")
    .button("Golden Antelope", "textures/lua/mythical_pets/renders/golden_antelope")
    .button("Guardian Wolf", "textures/lua/mythical_pets/renders/guardian_wolf")
    .button("Log Beaver", "textures/lua/mythical_pets/renders/log_beaver")
    .button("Moonlight Tiger", "textures/lua/mythical_pets/renders/moonlight_tiger")
    .button("Netherite Beetle", "textures/lua/mythical_pets/renders/netherite_beetle")
    .button("Pack Mule", "textures/lua/mythical_pets/renders/pack_mule")
    .button("Shadow Crow", "textures/lua/mythical_pets/renders/shadow_crow")
    .button("Sky Phoenix", "textures/lua/mythical_pets/renders/sky_phoenix")
    .button("Thunder Gryphon", "textures/lua/mythical_pets/renders/thunder_gryphon")
    .button("Venom Scorpion", "textures/lua/mythical_pets/renders/venom_scorpion")
    .button("Water Dolphin", "textures/lua/mythical_pets/renders/water_dolphin")
    .show(player).then(res => {
      if (!res.canceled) {
        switch (res.selection) {
          case 0:
            new ActionFormData()
              .title("Crystal Bunny")
              .body("The §3Crystal Bunny§r can be tamed by riding it until it loves you.\n\n- High jump ability.\n- HP: 15 \n- Healable with §6Golden Carrots§r.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 1:
            new ActionFormData()
              .title("Diamond Dragon")
              .body("The §bDiamond Dragon§r has a 25 percent chance to be tamed with a §bDiamond§r.\n\n- Drops §bDiamonds§r, §aEmeralds§r and §eGold Ingots§r every 80-100 seconds.\n- HP: 10 \n- Healable with §bDiamonds.§r")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 2:
            new ActionFormData()
              .title("Fiery Fox")
              .body("The §4Fiery Fox§r has a 10 percent chance to be tamed with Sweet Berries.\n\n- Follows you around.\n- HP: 35 \n- Healable§r with Sweet Berries.\n- Instantly §cheals§r you when your health is low. §7(90s cooldown)")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 3:
            new ActionFormData()
              .title("Fire Beetle")
              .body("The §cFire Beetle§r has a 40 percent chance to be tamed with Blaze Powder.\n\n- Follows you around.\n- HP: 20 \n- Healable with Blaze Powder.\n- Flies towards the mob you attack and explodes.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 4:
            new ActionFormData()
              .title("Golden Antelope")
              .body("The §6Golden Antelope§r has a 10 percent chance to be tamed with Wheat Seeds.\n\n- Follows you around.\n- HP: 25 \n- Healable with Wheat Seeds.\n- Gives you §dRegeneration II§r when you take damage. §7(10s cooldown)")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 5:
            new ActionFormData()
              .title("Guardian Wolf")
              .body("The §bGuardian Wolf§r has a 33 percent chance to be tamed with Bones.\n\n- Follows you around.\n- HP: 40 \n- Attacks nearby mobs.\n- Healable with meat.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 6:
            new ActionFormData()
              .title("Log Beaver")
              .body("The §9Log Beaver§r has a 10 percent chance to be tamed with a Stick.\n\n- Drops Wood, Sticks, Saplings and Apples every 50-70 seconds.\n- HP: 20 \n- Healable with Sticks.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 7:
            new ActionFormData()
              .title("Moonlight Tiger")
              .body("The §1Moonlight Tiger§r can be tamed by riding it until it loves you.\n\n- Fast movement.\n- HP: 30 \n- Gives you Night Vision effect when tamed.\n- Healable with meat.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 8:
            new ActionFormData()
              .title("Netherite Beetle")
              .body("The §8Netherite Beetle§r has a 30 percent chance to be tamed with a §7Netherite Ingot§r.\n\n- Drops §7Ancient Debris§r every 100-140 seconds.\n- HP: 5 \n- Healable with §8Netherite Ingots§r.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 9:
            new ActionFormData()
              .title("Pack Mule")
              .body("The §6Pack Mule§r has a 15 percent chance to be tamed with §6Wheat§r.\n\n- Follows you around.\n- HP: 20 \n- Healable with §6Wheat§r.\n- Carrys up to 27 stacks of items.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 10:
            new ActionFormData()
              .title("Shadow Crow")
              .body("The §8Shadow Crow§r has a 35 percent chance to be tamed with a §5Spider Eye§r.\n\n- Rideable; elevation can be controlled by looking §eup§r or §ddown§r.\n- HP: 15 \n- Healable with §5Spider Eyes.§r\n- Turns invisible at random intervals while riding it.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 11:
            new ActionFormData()
              .title("Sky Phoenix")
              .body("The §4Sky Phoenix§r has a 25 percent chance to be tamed with §6Blaze Powder§r.\n\n- Rideable; elevation can be controlled by looking §eup§r or §ddown§r.\n- HP: 40 \n- Healable with §6Blaze Powder§r.\n- Illuminates its surroundings.\n- Breathes §4fire§r when you interact with it using §4Red Dye§r while riding it.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 12:
            new ActionFormData()
              .title("Thunder Gryphon")
              .body("The §1Thunder Gryphon§r has a 40 percent chance to be tamed with §dAmethyst Shard§r.\n\n- Rideable; elevation can be controlled by looking §eup§r or §ddown§r.\n- 50 HP \n- Healable with §9Amethyst Shards§r.\n- Interact with §bLight Blue Dye§r while riding to summon §6lightning§r.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 13:
            new ActionFormData()
              .title("Venom Scorpion")
              .body("The §5Venom Scorpion§r has a 70 percent chance to be tamed with §5Poisonous §6Potato§r.\n\n- It §5poisons§r nearby mobs.\n- Follows you around.\n- HP: 25 \n- Healable with §5Poisonous §6Potatoes§r.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
          case 14:
            new ActionFormData()
              .title("Water Dolphin")
              .body("The §9Water Dolphin§r can be tamed by riding it until it loves you.\n\n- Allows you to travel §1underwater§r.\n- Allows you to breathe §1underwater§r.\n- HP: 10 \n- Healable with §3Salmon§r.")
              .button("§c< Back")
              .show(player).then(res => {
                if (!res.canceled) {
                  showInfoBook(player)
                }
              })
            break
        }
      }
    })
}