import { BlockPermutation, MolangVariableMap, TimeOfDay, system, world, ItemStack, StructureAnimationMode, StructureRotation, StructureSaveMode } from "@minecraft/server";
import { capitalizeFirst, getStringBeforeTent, checkLocation, getLocationbyFacingBlock, getEntityRotation, stringBetween, getGamemode, getElementPosition, getElementPositionArrayWithObjects } from "./helpers";
import { cameraCutscene } from "../events/camera";
import { ActionFormData, ModalFormData } from "@minecraft/server-ui";

const flagpoleColors = ["white", "black", "blue", "brown", "cyan", "gray", "green", "light_blue", "light_gray", "lime", "magenta", "orange", "pink", "purple", "red", "yellow"];

export class flagpoleHandler {
  static initialized = false;
  constructor() {
    this.initialize();
  }

  initialize() {
    if (!flagpoleHandler.initialized) {
      flagpoleHandler.initialized = true;
      this.processSubscriptions();
    } else {
    }
  }
  processSubscriptions() {
    world.afterEvents.playerInteractWithEntity.subscribe((event) => {
      const player = event.player;
      const typeId = player.typeId;
      if (typeId !== "minecraft:player") {
        return;
      }
      if (event.target.typeId.includes("hb_cb:") && event.target.typeId.includes("flagpole")) {
        const flagpole = event.target;
        if (!flagpole.getProperty("hb_cb:spawned")) return;
        const holdingItem = player.getComponent("equippable").getEquipment("Mainhand");
        if (!holdingItem) return;
        if (holdingItem.typeId.includes("minecraft:") && holdingItem.typeId.includes("dye")) {
          this.changeFlagpoleColor(player, flagpole, holdingItem);
        }
      } else return;
    });
    system.afterEvents.scriptEventReceive.subscribe((event) => {
      if (event.sourceEntity == undefined) return;
      else {
        if (event.sourceEntity.typeId.includes("hb_cb:") && event.sourceEntity.typeId.includes("flagpole")) {
          let flagpole = event.sourceEntity;
          switch (event.id) {
            case "hb_cb:despawn_tick_hit_trigger":
              if (!flagpole.getProperty("hb_cb:spawned")) return;
              if (flagpole.getProperty("hb_cb:despawn_tick") < 4) {
                flagpole.runCommand("/playanimation @s animation.hb_cb.flagpole.break");
                flagpole.runCommand("/event entity @s hb_cb:despawn_tick_hit");
              }
              break;
            case "hb_cb:flagpole_despawn":
              this.despawnFlagpole(flagpole);
              break;
            default:
              break;
          }
        }
      }
    });
    world.afterEvents.itemUse.subscribe((event) => {
      const player = event.source;
      const typeId = player.typeId;
      if (typeId !== "minecraft:player") {
        return;
      }
      const holdingItem = player.getComponent("equippable").getEquipment("Mainhand");
      if (holdingItem == undefined) {
        return;
      }
      if (holdingItem.typeId.includes("hb_cb:") && holdingItem.typeId.includes("flagpole")) this.spawnFlagpole(player, holdingItem);
    });
  }

  spawnFlagpole(player, item) {
    const raycastBlock = player.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: false, maxDistance: 8 });
    if (raycastBlock == undefined) return;
    else {
      let gamemodeCreative = getGamemode(player, 1);
      const location = raycastBlock.block.location;
      const face = raycastBlock.face;
      let placeLoc = getLocationbyFacingBlock(face, location);
      if (checkLocation(placeLoc, player, placeLoc, 1)) return;
      let block = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y, z: placeLoc.z });
      let block2 = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y + 1, z: placeLoc.z });
      block.setType("hb_cb:flagpole_block");
      block2.setType("hb_cb:flagpole_block");
      // world.sendMessage(block2.typeId);
      // world.sendMessage(block2.permutation.getState("minecraft:block_face"));
      let yRotation = getEntityRotation(player);
      let orientation;
      switch (yRotation) {
        case 0:
          orientation = "north";
          break;
        case 90:
          orientation = "east";
          break;
        case 180:
          orientation = "south";
          break;
        case 270:
          orientation = "west";
          break;

        default:
          break;
      }
      // world.sendMessage(orientation);
      block.setPermutation(
        BlockPermutation.resolve("hb_cb:flagpole_block", {
          "minecraft:block_face": orientation,
        })
      );
      block2.setPermutation(
        BlockPermutation.resolve("hb_cb:flagpole_block", {
          "minecraft:block_face": orientation,
        })
      );

      player.runCommand("/summon " + item.typeId + " " + placeLoc.x.toString() + " " + placeLoc.y.toString() + " " + placeLoc.z.toString() + " " + yRotation.toString() + " 0");

      if (!gamemodeCreative) {
        player.runCommand("/clear @s " + item.typeId + " 0 1");
      }
    }
  }

  despawnFlagpole(flagpole) {
    let colorIndex = flagpole.getProperty("hb_cb:flagpole_color");
    let oldColorPropertyValue = flagpoleColors[colorIndex];
    let spawnedItem = new ItemStack("hb_cb:" + oldColorPropertyValue + "_flagpole");
    world.getDimension(flagpole.dimension.id).spawnItem(spawnedItem, flagpole.location);

    flagpole.runCommand("/playanimation @s animation.hb_cb.flagpole.despawn");
    system.waitTicks(1).then(() => {
      if (flagpole.hasTag("hb_cb:start_block_despawn")) {
        flagpole.teleport({ x: flagpole.location.x, y: flagpole.location.y + 0.5, z: flagpole.location.z });
      }
      let block = world.getDimension(flagpole.dimension.id).getBlock({ x: flagpole.location.x, y: flagpole.location.y, z: flagpole.location.z });
      let block2 = world.getDimension(flagpole.dimension.id).getBlock({ x: flagpole.location.x, y: flagpole.location.y + 1, z: flagpole.location.z });
      block.setType("minecraft:air");
      block2.setType("minecraft:air");
      flagpole.remove();
    });
  }

  changeFlagpoleColor(player, flagpole, holdingItem) {
    let colorIndex = stringBetween(holdingItem.typeId, "minecraft:", "_dye");
    let newColorPropertyValue = getElementPosition(flagpoleColors, colorIndex);
    let oldColorIndex = flagpole.getProperty("hb_cb:flagpole_color");
    let checkColorPropertyValue = flagpoleColors[oldColorIndex];
    if (colorIndex == checkColorPropertyValue) return;
    else {
      let splashParticle = new MolangVariableMap();

      splashParticle.setFloat("variable.hb_cb_size", 0.5);
      splashParticle.setFloat("variable.hb_cb_radius", 0.5);
      splashParticle.setFloat("variable.hb_cb_y_offset", 1.3);
      try {
       player.playSound("mob.squid.hurt", {
        location: player.location,
        pitch: 1.3,
        volume: 0.75,
      });
        flagpole.dimension.spawnParticle("hb_cb:color_splash_" + colorIndex, { x: flagpole.location.x, y: flagpole.location.y, z: flagpole.location.z }, splashParticle);
      } catch (error) {}
      flagpole.setProperty("hb_cb:flagpole_color", newColorPropertyValue);
      player.runCommand("/clear @s " + holdingItem.typeId + " 0 1");
    }
  }
}
