import * as mc from "@minecraft/server";
import * as vector from "../utils/vector";

import { centerStructure, registerFeaturePosition, checkIfValidPosition } from "./structureManager";

const IS_ACTIVE = true;

const generatorTypes = {
  0: "Base",
  1: "Trunk",
  2: "Leg",
  3: "Stairs",
  4: "Chest",
  5: "Item frame",
  6: "Ramp",
  7: "Base Stairs",
};
const replacableBlocks = ["minecraft:air", "minecraft:short_grass", "minecraft:tall_grass", "minecraft:poppy", "minecraft:dandelion", "minecraft:sugar_cane"];
function isReplacableBlock(typeId) {
  for (let i = 0; i < replacableBlocks.length; i++) {
    if (typeId === replacableBlocks[i]) return true;
  }
  return false;
}
function cardinalToVector(direction) {
  switch (direction) {
    case "north":
      return { x: 0, y: 0, z: -1 };
    case "south":
      return { x: 0, y: 0, z: 1 };
    case "east":
      return { x: 1, y: 0, z: 0 };
    case "west":
      return { x: -1, y: 0, z: 0 };
    default:
      return { x: -1, y: 0, z: 0 };
  }
}
export function cardinalToStructure(direction) {
  switch (direction) {
    case "north":
      return "None";
    case "south":
      return "Rotate180";
    case "east":
      return "Rotate90";
    case "west":
      return "Rotate270";
    default:
      return "None";
  }
}
export function cardinalToRotation(direction) {
  switch (direction) {
    case "north":
      return 0;
    case "south":
      return 180;
    case "east":
      return 90;
    case "west":
      return 270;
    default:
      return 0;
  }
}

export function structureFeatureRegister(event) {
  event.blockComponentRegistry.registerCustomComponent("hf_mzs:generator", {
    onPlayerInteract(e) {
      if (e.player.getComponent("equippable").getEquipment("Mainhand")?.typeId === "hf_mzs:debugging_tool") {
        loadFeature(e.block, e.player.dimension);
        return;
      }
      const block = e.block;
      const currentType = block.permutation.getState("hf_mzs:type");
      const newType = currentType === 7 || currentType === undefined ? 0 : currentType + 1;
      mc.world.sendMessage(`Set state to ${newType} (${generatorTypes[newType]})`);
      block.setPermutation(block.permutation.withState("hf_mzs:type", newType));
    },
    onTick(e) {
      if (!IS_ACTIVE) return;
      loadFeature(e.block, e.dimension);
    },
  });
}

const rampOffsets = {
  north: { x: 1, y: 0, z: -2 },
  south: { x: 0, y: 0, z: 3 },
  east: { x: 3, y: 0, z: 1 },
  west: { x: -2, y: 0, z: 0 },
};

function loadFeature(block, dimension) {
  const direction = block.permutation.getState("minecraft:block_face");
  const type = block.permutation.getState("hf_mzs:type");
  //const type = 5;

  const loc = block.location;
  dimension.setBlockType(block.location, "air");
  if (type === 0) {
    let block = dimension.getBlockFromRay(loc, vector.down, {
      maxDistance: 300,
      includePassableBlocks: false,
    }).block.location;
    block.y++;

    let blocks = Math.abs(block.y - loc.y);
    for (let i = 0; i <= blocks; i++) {
      const blockType = Math.random() < 0.5 ? "red_terracotta" : "stripped_mangrove_log";
      dimension.setBlockType(vector.add(vector.multiply(vector.up, i), block), blockType);
    }
  } else if (type === 1) {
    let block = dimension.getBlockFromRay(loc, vector.down, {
      maxDistance: 300,
      includePassableBlocks: false,
    }).block.location;
    block.y++;

    let blocks = Math.abs(block.y - loc.y);
    for (let i = 0; i <= blocks; i++) {
      const blockType = Math.random() < 0.13 ? "hf_mzs:clawed_log" : "stripped_jungle_wood";
      dimension.setBlockType(vector.add(vector.multiply(vector.up, i), block), blockType);
    }
  } else if (type === 2) {
    let block = dimension.getBlockFromRay(loc, vector.down, {
      maxDistance: 300,
      includePassableBlocks: false,
    }).block.location;
    block.y++;
    dimension.runCommand(`fill ${loc.x} ${loc.y} ${loc.z} ${block.x} ${block.y} ${block.z}
                stripped_mangrove_log`);
  } else if (type === 3) {
    const delta = cardinalToVector(direction);

    let pivot = loc;
    let current = 0;

    while (isReplacableBlock(dimension.getBlock(pivot).typeId) && current <= 4) {
      const slabType = current % 2 === 0 ? "top" : "bottom";
      dimension.runCommand(`setblock ${pivot.x} ${pivot.y} ${pivot.z}
                    acacia_slab ["minecraft:vertical_half"="${slabType}"] replace`);

      current++;
      if (current !== 0 && current % 2 === 0) pivot.y--;
      if (current != 4) pivot = vector.add(pivot, delta);
      else {
        pivot.y -= 1;
        let block = dimension.getBlockFromRay(pivot, vector.down, {
          maxDistance: 300,
          includePassableBlocks: false,
        }).block.location;
        block.y++;

        let blocks = Math.abs(block.y + 2 - loc.y);
        for (let i = 0; i <= blocks; i++) {
          const blockType = "stripped_mangrove_log";
          const blockPos = vector.add(vector.multiply(vector.up, i), block);
          dimension.setBlockType(blockPos, blockType);

          const weirdoDir = () => {
            switch (direction) {
              case "south":
                return 3;
              case "north":
                return 2;
              case "east":
                return 5;
              case "west":
                return 4;
              default:
                return 0;
            }
          };
          const ladderPos = vector.add(blockPos, delta);
          //mc.world.sendMessage(`${pivot.x}   ${pivot.y}   ${pivot.z}   ;   ${right.x}   ${right.y}   ${right.z}`)
          dimension.runCommand(`setblock ${ladderPos.x} ${ladderPos.y} ${ladderPos.z}
                        ladder ["facing_direction"=${weirdoDir()}] replace`);
        }
      }
    }
  } else if (type === 4) {
    dimension.setBlockType(loc, "chest");
    const rolls = Math.floor(Math.random() * 6) + 3;
    const inventory = dimension.getBlock(loc).getComponent("inventory");

    for (let i = 0; i <= rolls; i) {
      const slot = Math.floor(Math.random() * 27);
      if (inventory.container.getItem(slot) !== undefined) continue;
      dimension.runCommand(`loot replace block ${loc.x} ${loc.y} ${loc.z}
                    slot.container ${slot} loot "hf/mzs/umvuthana_chest"`);
      i++;
    }
  } else if (type === 5) {
    mc.world.structureManager.place("hf_mzs:umvuthana_mask" + (Math.floor(Math.random() * 5) + 1), dimension, loc, { rotation: cardinalToStructure(direction) });
  } else if (type === 6) {
    dimension.runCommand(`setblock ${loc.x} ${loc.y} ${loc.z} acacia_slab
                ["minecraft:vertical_half"="top"] replace`);
    if (Math.random() < 0.5) return;
    const position = centerStructure(vector.add(loc, rampOffsets[direction]), "hf_mzs:umvuthana_ramp_extension", -1, direction === "north" || direction === "south" ? 0 : 1);
    if (!checkIfValidPosition(position, 3.5)) return;
    mc.world.structureManager.place("hf_mzs:umvuthana_ramp_extension", dimension, position, { rotation: cardinalToStructure(direction) });
    registerFeaturePosition({ location: position, radius: 3.5 });
  } else if (type === 7) {
    const delta = cardinalToVector(direction);

    let pivot = loc;
    let current = 0;

    while (isReplacableBlock(dimension.getBlock(pivot).typeId) && current < 10) {
      const right = vector.add(vector.cross(delta, vector.up), pivot);
      const left = vector.add(vector.cross(delta, vector.down), pivot);
      const right2 = vector.add(vector.multiply(vector.cross(delta, vector.up), 2), pivot);
      const left2 = vector.add(vector.multiply(vector.cross(delta, vector.down), 2), pivot);
      const weirdoDir = () => {
        switch (direction) {
          case "north":
            return 2;
          case "south":
            return 3;
          case "east":
            return 1;
          case "west":
            return 0;
          default:
            return 0;
        }
      };
      //mc.world.sendMessage(`${pivot.x}   ${pivot.y}   ${pivot.z}   ;   ${right.x}   ${right.y}   ${right.z}`)
      dimension.runCommand(`setblock ${pivot.x} ${pivot.y} ${pivot.z}
                    red_sandstone_stairs ["weirdo_direction"=${weirdoDir()}] replace`);
      dimension.runCommand(`setblock ${right.x} ${right.y} ${right.z}
                    acacia_stairs ["weirdo_direction"=${weirdoDir()}] replace`);
      dimension.runCommand(`setblock ${left.x} ${left.y} ${left.z}
                    acacia_stairs ["weirdo_direction"=${weirdoDir()}] replace`);
      dimension.runCommand(`setblock ${right2.x} ${right2.y} ${right2.z}
                    hf_mzs:generator ["hf_mzs:type"=0, "minecraft:block_face"="down"] replace`);
      dimension.runCommand(`setblock ${left2.x} ${left2.y} ${left2.z}
                    hf_mzs:generator ["hf_mzs:type"=0, "minecraft:block_face"="down"] replace`);

      current++;
      pivot.y--;
      pivot = vector.add(pivot, delta);
    }
  }
}
