import { system, world } from "@minecraft/server";
import noise from "./noise";
import { ScoreboardDB } from "./eternal/modules/scoreboardDB";

const db = new ScoreboardDB("biomeGenerator");

// Seed the noise generator for consistent results
noise.seedWithString("Eternal");

// Function to replace blocks in vanilla biomes based on noise map
function replaceBiomeBlocksAroundPlayer(player, chunkRadius) {
  const playerChunkX = Math.floor(player.location.x / 16);
  const playerChunkZ = Math.floor(player.location.z / 16);

  // Retrieve or initialize the replaced chunks for this player
  const loadedChunks = db.get("biomeGenerator") ?? new Set();

  for (let chunkX = playerChunkX - chunkRadius; chunkX <= playerChunkX + chunkRadius; chunkX++) {
    for (let chunkZ = playerChunkZ - chunkRadius; chunkZ <= playerChunkZ + chunkRadius; chunkZ++) {
      const chunkLocation = `${chunkX},${chunkZ}`; // Use string for storing chunk location

      if (loadedChunks.has(chunkLocation)) continue;
      try {
        replaceBiomeBlocksUsingNoise(chunkX * 16, chunkZ * 16);
        loadedChunks.add(chunkLocation); // Mark chunk as processed
      } catch (error) {}
    }
  }

  // Update the replaced chunks for the player in the database
  db.set("biomeGenerator", loadedChunks);
}

// Replace specific blocks using noise map for custom biome distribution
function replaceBiomeBlocksUsingNoise(xStart, zStart) {
  const chunkSize = 16;

  for (let x = xStart; x < xStart + chunkSize; x++) {
    for (let z = zStart; z < zStart + chunkSize; z++) {
      const noiseValue = noise.perlin2(x / 300, z / 300); // Generate noise value (scaled for smoothness)

      // Define biome block replacements based on noise value
      if (noiseValue > 0.1) {
        // replaceBlockColumn(x, z, "minecraft:tallgrass", "ecbl_bc:dry_grass");
        replaceBlockColumn(x, z);
      } else {
        // replaceBlockColumn(x, z, "minecraft:grass_block", "minecraft:stone");
      }
    }
  }
}

// Replace specified block types in a column with custom block types
function replaceBlockColumn(x, z) {
  const blocksToReplace = {
    vegitations: {
      from: [
        "minecraft:short_grass",
        "minecraft:tall_grass",
        "minecraft:poppy",
        "minecraft:pink_petals",
        "minecraft:reeds",
        "minecraft:oxeye_daisy",
        "minecraft:dandelion",
      ],
      to: ["ecbl_bc:dry_grass"],
    },
    blocks: {
      from: ["minecraft:grass_block", "minecraft:dirt"],
      to: ["ecbl_bc:dry_grass_block"],
    },
  };
  const chooseRandomFromArray = (array) => {
    return array[Math.floor(Math.random() * array.length)];
  };
  const dimension = world.getDimension("overworld");

  const topBlock = dimension.getTopmostBlock({ x: x, z: z });

  // Replace blocks
  let currentBlock = topBlock;
  const blocks = blocksToReplace.blocks;
  let tries = 0;
  while (tries <= 10) {
    if (blocks.from.includes(currentBlock.typeId)) {
      tries = 0;

      currentBlock.setType(chooseRandomFromArray(blocks.to));
    } else tries++;
    currentBlock = currentBlock.below();
  }

  // Replace vegitations

  const veg = topBlock.above();
  const vegitations = blocksToReplace.vegitations;
  if (vegitations.from.includes(veg.typeId)) {
    const ranVeg = chooseRandomFromArray(vegitations.to);
    veg.setType(ranVeg);
  }
}

// Replace specified block types in a column with custom block types
function replaceVegitation(x, z, targetBlock, replacementBlock) {
  const dimension = world.getDimension("overworld");

  const topBlock = dimension.getTopmostBlock({ x: x, z: z });
  let currentBlock = topBlock.above();
  while (currentBlock.typeId === targetBlock) {
    currentBlock.setType(replacementBlock);
    currentBlock = currentBlock.above();
  }
}

// Main execution: Continuously check for player movement
system.runInterval(() => {
  world.getAllPlayers().forEach((player) => {
    const chunkRadius = 16; // Number of chunks around the player to process
    replaceBiomeBlocksAroundPlayer(player, chunkRadius);
  });
}, 100);
