import { system, world, BlockVolume } from "@minecraft/server";

const testBiomeBlock = {
  dead_forest: ["hb_hr:dead_roots", "hb_hr:dirty_dead_roots", "hb_hr:dried_dirt", "hb_hr:rotten_soil"],
  // dead_forest: ["hb_hr:stripped_blight_log", "hb_hr:stripped_blight_wood","hb_hr:blight_leaves", "hb_hr:blight_log", "hb_hr:blight_sapling", "hb_hr:blight_wood", "hb_hr:chiseled_grim_stone_bricks",  "hb_hr:dead_bush", "hb_hr:dead_grass", "hb_hr:dead_root_carpet", "hb_hr:dead_roots", "hb_hr:dirty_dead_roots", "hb_hr:dried_dirt", "hb_hr:hive", "hb_hr:hive_carpet","hb_hr:large_hive_egg", "hb_hr:hive_vine","hb_hr:cracked_grim_stone_bricks","hb_hr:grim_stone", "hb_hr:grim_stone_bricks", "hb_hr:grim_stone_chunks",  "hb_hr:infested_grim_stone_bricks",  "hb_hr:polished_grim_stone", "hb_hr:rotten_soil", "hb_hr:small_hive_egg", "hb_hr:soul_ore", ],
  cursed_meadows: ["hb_hr:ash_block", "hb_hr:cursed_grass_block", "hb_hr:dried_cursed_grass_block"],
  // cursed_meadows: ["hb_hr:cursed_leaves", "hb_hr:cursed_log", "hb_hr:cursed_sapling", "hb_hr:cursed_wood", "hb_hr:cursed_bush", "hb_hr:cursed_grass", "hb_hr:stripped_cursed_log", "hb_hr:stripped_cursed_wood", "hb_hr:ash_block", "hb_hr:cursed_grass_block", "hb_hr:dried_cursed_grass_block", "hb_hr:cursed_tall_grass", "hb_hr:cursed_vine"],

  vanilla: ["minecraft:dirt"],
};

const nonSolidBlocks = [
  "minecraft:flower",
  "minecraft:dandelion",
  "minecraft:poppy",
  "minecraft:grass",
  "minecraft:leaves",
  "minecraft:short_grass",
  "minecraft:tall_grass",
  "minecraft:coral",
  "minecraft:sea_pickle",
  "minecraft:waterlily",
  "minecraft:melon_stem",
  "minecraft:vine",
  "minecraft:nether_wart",
  "minecraft:beetroot", // and any other plant blocks you want to avoid
];

export class fogHandler {
  static initialized = false;
  static playerBiomeMap = new Map(); // Speichert zuletzt erkannte Biome für jeden Spieler

  constructor() {
    this.initialize();
  }

  initialize() {
    if (!fogHandler.initialized) {
      fogHandler.initialized = true;
      this.processSubscriptions();
    }
  }

  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;
            this.handleFogInNewBiomes(player);
            // this.handleParticles(player);
          });
        }
        curTick++;
      } catch (e) {
        // console.warn(e);
      }
    }, 40);
  }

  handleFogInNewBiomes(player) {
    if (player.dimension.id !== "minecraft:overworld") return;

    const volume = new BlockVolume({ x: player.location.x + 5, y: player.location.y + 5, z: player.location.z + 5 }, { x: player.location.x - 5, y: player.location.y - 5, z: player.location.z - 5 });

    const locations = volume.getBlockLocationIterator();
    const foundBiomes = new Set(); // Hier werden gefundene Biome gesammelt

    for (const location of locations) {
      const block = player.dimension.getBlock(location);
      if (!block) continue;
      const blockType = block.typeId;
      // Überprüfe für jedes Biome in testBiomeBlock, ob der Blocktyp dazugehört
      for (const [biome, blocks] of Object.entries(testBiomeBlock)) {
        if (blocks.includes(blockType)) {
          foundBiomes.add(biome);
        }
      }
    }

    // Konvertiere das Set in ein Array, um damit weiterzuarbeiten
    let biomeArray = [...foundBiomes];

    // --- Anpassung für Custom-/Vanilla-Logik ---
    // Wenn Biome gefunden wurden:
    if (biomeArray.length > 0) {
      // Prüfe, ob eines der gefundenen Biome NICHT "vanilla" ist
      const hasCustomBiome = biomeArray.some((b) => b !== "vanilla");
      if (hasCustomBiome) {
        // Wenn custom Biome vorhanden sind, entferne "vanilla" aus dem Array,
        // um ein doppeltes Setzen zu vermeiden.
        biomeArray = biomeArray.filter((b) => b !== "vanilla");
      } else {
        // Falls ausschließlich "vanilla" gefunden wurde, stelle sicher,
        // dass nur ein Eintrag vorhanden ist.
        biomeArray = ["vanilla"];
      }
    } else {
      // Falls gar keine Biome gefunden wurden, standardmäßig auf "vanilla" setzen.
      biomeArray.push("vanilla");
    }
    // -------------------------------------------

    // Prüfe, ob sich die Biome seit dem letzten Tick geändert haben
    const lastBiomes = fogHandler.playerBiomeMap.get(player.name) || [];
    if (JSON.stringify(biomeArray) === JSON.stringify(lastBiomes)) {
      return;
    }

    // Speichere die aktuellen Biome für den Spieler
    fogHandler.playerBiomeMap.set(player.name, biomeArray);

    // Entferne alle alten Biome-Tags und Fog-Einstellungen
    for (const biome of Object.keys(testBiomeBlock)) {
      player.removeTag(`hb_hr:in_${biome}`);
      player.runCommand(`fog @s remove hb_hr_biome_fog`);
    }

    // Falls Biome (nun garantiert mindestens "vanilla") vorhanden sind, setze Fog & Tags
    if (biomeArray.length > 0) {
      biomeArray.forEach((biome) => {
        // player.runCommand("/music stop 2");
        if (biome != "vanilla") {
          // player.runCommand("/music play " + biome + "_sound 0.1 2 loop");
          player.runCommand(`fog @s push hb_hr:${biome} hb_hr_biome_fog`);
        }
        player.addTag(`hb_hr:in_${biome}`);
        const biomeEntries = Object.keys(testBiomeBlock);
        const index = biomeEntries.indexOf(biome);
        player.setDynamicProperty("hb_hr:biome_tag", index);
      });
    }
  }
}
