import { world, system, EntityEquippableComponent, Player } from "@minecraft/server";
import { ActionFormData } from "@minecraft/server-ui";
import * as menu from "./Menus"
import * as scores from "./Scores"
import * as tomes from "./Tomes"
import * as wand from "./Wand"
import { namespace } from "./Namespace";
import * as spellEvent from "./Spells/SpellEvents";
import { tickCooldowns } from "./Cooldowns";
import { setLightBlocks } from "./Spells/7. Light";
import { shieldTick } from "./Spells/11. Shield";

//Initialization
let initDone = false
world.afterEvents.playerSpawn.subscribe((event) => {
  const player = event.player;
  if (!initDone) {
    scores.createScoreboards();
    world.getDimension("overworld").runCommand("/execute unless entity @e[tag=BC_Magic_Init] run function blockception/magic/init/locked_scores");
    initDone = true;
  }
  player.runCommand("/execute as @s[tag=!BC_Magic_Init] at @s run function blockception/magic/init/scoreboard");
  scores.syncSpellLocked();
});

//Run every tick
system.runInterval(tickFunctions, 1);
function tickFunctions() {
  //Tick players cooldowns down
  tickCooldowns();
  //Set the light blocks for any players using light spell
  setLightBlocks();
  //Teleports shields for any players using shield spell
  shieldTick();
}

//Listen for spell events
system.afterEvents.scriptEventReceive.subscribe((event) => {
  //let eventName = event.id.split(":");
  let eventNamespace = event.id.split(":")[0];
  let command = event.id.split(":")[1];
  let entityName, location, dimension;
  if (event.sourceEntity != undefined) {
    entityName = event.sourceEntity.typeId;
    location = event.sourceEntity.location;
    dimension = event.sourceEntity.dimension;
  }
  if (eventNamespace == namespace) {
    switch (command) {
      case ("spell_event"): {
        if (entityName == undefined) {
          return;
        }
        if (entityName.startsWith(namespace) && entityName.endsWith("_spell")) {
          event.sourceEntity.triggerEvent("self:despawn");
        }
        spellEvent.doSpellEvent(entityName, location, dimension);
        return;
      }
      default: {
        return;
      }
    }
  }
});



//Detect when entities die. If killed by magic, drop an item?
world.afterEvents.entityDie.subscribe((event) => {
  const deadEntity = event.deadEntity;
  const source = event.damageSource;

  if (deadEntity == undefined) {
    return;
  };
  //world.sendMessage(`${deadEntity.typeId} killed by magic`);
});

//Detect entities getting hit
world.afterEvents.entityHurt.subscribe((event) => {
  const entity = event.hurtEntity;
  const source = event.damageSource;
  
  if (source.damagingEntity == undefined) {
    return;
  }
  if (source.damagingEntity.typeId.startsWith(`${namespace}:`) && source.damagingEntity.typeId.endsWith("_spell")) {
    spellEvent.doHurtSpellEvent(source.damagingEntity.typeId, entity);
  };
});

//Detect items being used
world.afterEvents.itemUse.subscribe((event) => {
  const player = event.source;
  const itemID = event.itemStack.typeId
  if (player == undefined) {
    return;
  }
  if (player.typeId != "minecraft:player") {
    return;
  }//Tome usage
  if (itemID.includes(`${namespace}:tome_`)) {
    tomes.tomeUse(player, event.itemStack);
    return;
  }//Wand usage
  if (itemID.includes(`${namespace}:wand_`)) {
    //If sneaking, open the wand menu
    if (player.isSneaking) {
      menu.wandMenu(player);
      return;
    }
    //If not sneaking, check interaction with sorcery table first
    let block = player.getBlockFromViewDirection({maxDistance: 5})?.block;
    if (block == undefined) {
      wand.cast(player);
      return;
    }
    let tags = block.getTags();
    let magicInteract = false;
    for (let x = 0; x < tags.length; x++) {
      if (tags[x] == "sorcery_table") {
        magicInteract = true;
      }
    }
    if (magicInteract) {
      scores.syncSpellLocked();
      menu.spellsMenu(player);
      return;
    }
    if (!magicInteract && !player.isSneaking) {
      wand.cast(player);
      return;
    }
  }
});