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

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

  initialize() {
    if (!ceramicPotHandler.initialized) {
      ceramicPotHandler.initialized = true;
      this.processSubscriptions();
    } else {
    }
  }
  processSubscriptions() {
    let curTick = 0;
    const INIT_TIME = 0;

    system.runInterval(() => {
      try {
        if (curTick > INIT_TIME) {
          const allPlayers = world.getAllPlayers();
          allPlayers.forEach((player) => {
            if (!player.isValid()) return;
            else {
              replaceFilledEmptyPots(player);
              checkBelowEntityDespawn(player, "ceramic_pot");
            }
          });
        }
        curTick++;
      } catch (e) {
        console.warn(e);
      }
    }, 0);

    world.afterEvents.playerInteractWithEntity.subscribe((event) => {
      const player = event.player;
      const typeId = player.typeId;
      if (typeId !== "minecraft:player") {
        return;
      }
      if (event.target.typeId == "hb_cb:ceramic_pot") {
        const ceramicPot = event.target;
        this.interactAbility(player, ceramicPot);
      } else return;
    });
    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:ceramic_pot_item")) this.spawnceramicPot(player, holdingItem);
    });
    system.afterEvents.scriptEventReceive.subscribe((event) => {
      if (event.sourceEntity == undefined) return;
      else {
        if (event.sourceEntity.typeId.includes("hb_cb:") && event.sourceEntity.typeId.includes("ceramic_pot")) {
          let ceramic_pot = event.sourceEntity;
          switch (event.id) {
            case "hb_cb:despawn_tick_hit_trigger":
              if (ceramic_pot.getProperty("hb_cb:despawn_tick") < 4) {
                ceramic_pot.runCommand("/playsound block.decorated_pot.insert_fail @a[r=10] ~~~ 1 1.1");
                ceramic_pot.runCommand("/playanimation @s animation.hb_cb.ceramic_cooking_pot.break");
                ceramic_pot.runCommand("/event entity @s hb_cb:despawn_tick_hit");
              }
              break;
            case "hb_cb:ceramic_pot_despawn":
              this.despawnceramicPot(ceramic_pot);
              break;
            default:
              break;
          }
        }
      }
    });
  }
  interactAbility(player, ceramic_pot) {
    const hand = player.getComponent("equippable").getEquipment("Mainhand");
    if (!hand || hand.typeId !== "minecraft:bowl") return;

    // read how many bowls are “inside” the pot right now
    let inside = ceramic_pot.getProperty("hb_cb:load_amount") || 0;
    if (inside <= 0) {
      return;
    }

    // spawn one bowl-worth of food
    const foodType = ceramic_pot.getProperty("hb_cb:food_type");
    const spawned = new ItemStack("hb_cb:" + foodType, 1);
    const dim = ceramic_pot.dimension.id;
    const loc = ceramic_pot.location;
    let newBowl = world.getDimension(dim).spawnItem(spawned, { x: loc.x, y: loc.y + 0.1, z: loc.z });
    newBowl.clearVelocity();

    // now remove one from the count, never dropping below zero
    inside = Math.max(inside - 1, 0);

    player.runCommand("/playsound hb_cb:kettle_place_food @a[r=10] ~~~ 1 1");
    try {
      ceramic_pot.dimension.spawnParticle("hb_cb:ceramic_pot_take_food", { x: loc.x, y: loc.y + 0.1, z: loc.z });
    } catch (error) {}
    ceramic_pot.setProperty("hb_cb:load_amount", inside);
    player.runCommand("/clear @s " + hand.typeId + " 0 1");
  }

  spawnceramicPot(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, 0)) return;

      // let ceramic_pot = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
      let yRotation = getEntityRotation(player);

      // player.runCommand("/playsound block.lantern.place @a[r=10] ~~~ 1 1");

      let block = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y, z: placeLoc.z });
      block.setType("hb_cb:ceramic_pot");
      player.runCommand("/summon " + getStringBefore(item.typeId, "_item") + " " + placeLoc.x.toString() + " " + placeLoc.y.toString() + " " + placeLoc.z.toString() + " " + yRotation.toString() + " 0");

      let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
        families: ["hb_cb_ceramic_pot"],
        location: placeLoc,
        closest: 1,
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        let itemFoodType = item.getDynamicProperty("hb_cb:food_type") ?? "empty";
        let itemFoodAmount = item.getDynamicProperty("hb_cb:load_amount") ?? 0;
        nearbyEntities[0].setProperty("hb_cb:food_type", itemFoodType);
        nearbyEntities[0].setProperty("hb_cb:load_amount", itemFoodAmount);
      }

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

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

      let entityFoodType = ceramic_pot.getProperty("hb_cb:food_type") ?? "empty";
      let entityFoodAmount = ceramic_pot.getProperty("hb_cb:load_amount") ?? 0;
      if (entityFoodAmount > 0) {
        spawnedItem = new ItemStack("hb_cb:ceramic_pot_item_filled");
        spawnedItem.setDynamicProperty("hb_cb:food_type", entityFoodType);
        spawnedItem.setDynamicProperty("hb_cb:load_amount", entityFoodAmount);

        spawnedItem.setLore([
          "§r§2Contains: §r§o" +
            entityFoodType
              .split("_")
              .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
              .join(" ") +
            " §r§a" +
            entityFoodAmount.toString() +
            "/3",
        ]);
      } else {
        spawnedItem = new ItemStack("hb_cb:ceramic_pot_item_empty");
      }

      world.getDimension(ceramic_pot.dimension.id).spawnItem(spawnedItem, ceramic_pot.location);
      ceramic_pot.remove();
    });
  }
}

function replaceFilledEmptyPots(player) {
  const playerContainer = player.getComponent("inventory").container;
  for (let i = 0; i < playerContainer.size; i++) {
    const item = playerContainer.getItem(i);
    if (!item) continue;
    if (item.typeId == "hb_cb:ceramic_pot_item_filled") {
      let itemFoodAmount = item.getDynamicProperty("hb_cb:load_amount") ?? 0;
      if (itemFoodAmount > 0) continue;
      let replaceItem = new ItemStack("hb_cb:ceramic_pot_item_empty");
      playerContainer.setItem(i, replaceItem);
    }
  }
}
