import {
  world,
  system,
  MolangVariableMap,
  EntityDamageCause,
} from "@minecraft/server";
import { get_randomWithWeight } from "./time_events";
import { get_PlayerGroups, CurrentEventProp } from "./utilities";

const eventId = "blood_moon";
const mobTypeIds = [
  {
    id: "minecraft:wolf",
    w: 30,
    bound: 0,
  },
  {
    id: "minecraft:vindicator",
    w: 10,
    bound: 0,
  },
  {
    id: "minecraft:witch",
    w: 5,
    bound: 0,
  },
  {
    id: "tvf_randev:evil_eye",
    w: 5,
    bound: 0,
  },
];
const mobsId_toReplace = [
  {
    id: "minecraft:creeper",
    chance: 0.3,
  },
  {
    id: "minecraft:skeleton",
    chance: 0.75,
  },
  {
    id: "minecraft:stray",
    chance: 0.75,
  },
  {
    id: "minecraft:bogged",
    chance: 0.75,
  },
  {
    id: "minecraft:spider",
    chance: 0.5,
  },
  {
    id: "minecraft:zombie",
    chance: 0.75,
  },
  {
    id: "minecraft:zombie_villager",
    chance: 0.75,
  },
  {
    id: "minecraft:husk",
    chance: 0.75,
  },
];
//******************************************** */
export function blood_moon_MAIN(dimension) {
  system.runInterval(() => {
    const event = CurrentEventProp.getProp();
    if (!(event.id == eventId && event.status == "is_happening")) return;
    if (event.timer >= 0) {
      if (event.timer == 1) {
        world.sendMessage([
          {
            translate: `tvf_randev.event.start.${event.id}`,
          },
        ]);
      }
      get_PlayerGroups(dimension, 25).forEach((group) => {
        visualEffects(group);
      });
      get_PlayerGroups(dimension, 110).forEach((group) => {
        placeMoon(group.location);
      });
      /*dimension.getPlayers().forEach((player) => {
        mobHorde(player);
      });*/
      event.timer += 1;
    }
    if (
      event.forcedEnd == true ||
      (event.timer >= event.maxDuration &&
        (world.getTimeOfDay() > 23000 || world.getTimeOfDay() < 13000))
    ) {
      event.status = "is_end";
      system.runTimeout(() => {
        dimension.runCommand("/fog @a remove tvf_randev:fogsID");
      }, 20 * 10);
      world.sendMessage([
        {
          translate: `tvf_randev.event.end.${event.id}`,
        },
      ]);
    }
    CurrentEventProp.update(event);
  });
  function visualEffects(group) {
    if (system.currentTick % 100 != 0) return;

    group.players.forEach((player) => {
      if (player.graphicsMode == "Deferred") {
        player.runCommand(
          "/fog @s push tvf_randev:blood_moon_vol tvf_randev:fogsID"
        );
      } else {
        player.runCommand(
          "/fog @s push tvf_randev:blood_moon_fog tvf_randev:fogsID"
        );
      }
    });

    dimension.spawnParticle("tvf_randev:blood_moon_sky", group.location);
  }
  function placeMoon(location) {
    if (system.currentTick % 100 != 0) return;
    let map = new MolangVariableMap();
    map.setFloat("daytime", world.getTimeOfDay() - 12500);
    dimension.spawnParticle("tvf_randev:blood_moon", location, map);
  }
  world.afterEvents.entitySpawn.subscribe((mobspawn) => {
    if (mobspawn.cause != "Spawned") return;

    const event = CurrentEventProp.getProp();
    if (!(event.id == eventId && event.status == "is_happening")) return;

    const inputMob = mobspawn.entity;
    if (
      inputMob &&
      inputMob.isValid &&
      mobsId_toReplace.some(
        (mob) => mob.id === inputMob.typeId && Math.random() < mob.chance
      )
    ) {
      const outputMob_id = get_randomWithWeight(mobTypeIds);
      const location = inputMob.location;
      inputMob.remove();
      const outputMob = dimension.spawnEntity(outputMob_id, location);

      if (outputMob_id == "minecraft:wolf") {
        const spawn_event = [
          "minecraft:spawn_wild_pale",
          "minecraft:spawn_wild_ashen",
          "minecraft:spawn_wild_black",
          "minecraft:spawn_wild_chestnut",
          "minecraft:spawn_wild_snowy",
          "minecraft:spawn_wild_spotted",
          "minecraft:spawn_wild_striped",
          "minecraft:spawn_wild_woods",
        ];

        const player = dimension.getEntities({
          type: "minecraft:player",
          location: outputMob.location,
          closest: 1,
        })[0];

        const event =
          spawn_event[Math.floor(Math.random() * spawn_event.length)];
        outputMob.triggerEvent(event);
        outputMob.triggerEvent("minecraft:entity_spawned");
        outputMob.triggerEvent("minecraft:become_angry");
        outputMob.applyDamage(0.1, {
          cause: EntityDamageCause.entityAttack,
          damagingEntity: player,
        });
      }
    }
  });
}
