import { Dimension, world } from "@minecraft/server";
import {
  eventsDefault,
  currentEventDefault,
  anyEventAtDayChanceDefault,
} from "./configs/eventConfig";

//Сломал блок - получил координату в лог
export function blockCoordinatesHelper(
  get_id = false,
  cancel_event = true,
  get_above = false
) {
  world.beforeEvents.playerBreakBlock.subscribe((event) => {
    let data = {
      x: event.block.location.x,
      y: event.block.location.y,
      z: event.block.location.z,
      id: event.block.typeId,
    };
    if (get_above) data.y++;
    if (get_id)
      console.warn(`{id:${data.id} ,x: ${data.x}, y: ${data.y}, z: ${data.z}}`);
    else console.warn(`{x: ${data.x}, y: ${data.y}, z: ${data.z}}`);
    event.cancel = cancel_event;
  });
}

export function get_PlayerGroups(dimension, bound) {
  if (!(dimension instanceof Dimension)) return [];

  const allPlayers = dimension.getPlayers();
  const groups = [];

  for (let player of allPlayers) {
    try {
      const playerLoc = player.location;

      const group = findNearbyGroup(playerLoc, bound, groups);
      if (group) {
        group.players.push(player);
      } else {
        groups.push({
          players: [player],
          location: playerLoc,
        });
      }
    } catch {
      groups.push({
        players: [player],
        location: { x: 0, y: 0, z: 0 },
      });
    }
  }

  return groups;
}

function findNearbyGroup(location, range, groups) {
  for (let group of groups) {
    const dist = Math.sqrt(
      (location.x - group.location.x) ** 2 +
        (location.z - group.location.z) ** 2
    );
    if (dist < range) {
      return group;
    }
  }
  return null;
}

export function anyPlayerNotUnderground() {
  let bool = false;
  world
    .getDimension("overworld")
    .getPlayers()
    .forEach((player) => {
      if (player.location.y > 50) bool = true;
    });
  return bool;
}
export function anyPlayerInDimension(dimensionId) {
  if (dimensionId == "all") return true;
  const players = world.getDimension(dimensionId).getPlayers();
  if (players == undefined) return false;
  if (players.length == 0) return false;
  else return true;
}
//worldProp
export var AllEventProp;
(function (AllEventProp) {
  const eventsPropId = "tvf_randev:allEvents";
  function update(obj) {
    if (world.getDynamicProperty(eventsPropId) == undefined) {
      world.setDynamicProperty(eventsPropId, JSON.stringify(eventsDefault));
    }
    world.setDynamicProperty(eventsPropId, JSON.stringify(obj));
  }
  function getProp() {
    if (world.getDynamicProperty(eventsPropId) == undefined) return undefined;
    const data = world.getDynamicProperty(eventsPropId);
    return JSON.parse(data);
  }
  function getAvailableRandomEvents() {
    const filteredEvents = {};
    const events = getProp();
    for (const [eventId, eventData] of Object.entries(events)) {
      if (eventData.is_available === true && eventData.is_random === true) {
        filteredEvents[eventId] = eventData;
      }
    }
    return filteredEvents;
  }
  function getSheet_translateKey_Available() {
    const sheet = {};
    const data = getProp();
    for (const [eventId, eventData] of Object.entries(data)) {
      if (eventId == "none") continue;
      sheet[eventId] = {
        translateKey: "tvf_randev.event.name." + eventId,
        is_available: eventData.is_available,
      };
    }
    return sheet;
  }
  AllEventProp.update = update;
  AllEventProp.getProp = getProp;
  AllEventProp.getAvailableRandomEvents = getAvailableRandomEvents;
  AllEventProp.getSheet_translateKey_Available =
    getSheet_translateKey_Available;
})(AllEventProp || (AllEventProp = {}));
export var CurrentEventProp;
(function (CurrentEventProp) {
  const currentEventPropId = "tvf_randev:currEvent";
  function update(obj) {
    if (world.getDynamicProperty(currentEventPropId) == undefined) {
      world.setDynamicProperty(
        currentEventPropId,
        JSON.stringify(currentEventDefault)
      );
    }
    world.setDynamicProperty(currentEventPropId, JSON.stringify(obj));
  }
  function getProp() {
    if (world.getDynamicProperty(currentEventPropId) == undefined)
      return undefined;
    const data = world.getDynamicProperty(currentEventPropId);
    return JSON.parse(data);
  }
  CurrentEventProp.update = update;
  CurrentEventProp.getProp = getProp;
})(CurrentEventProp || (CurrentEventProp = {}));
export var AnyEventAtDayChance;
(function (AnyEventAtDayChance) {
  const propId = "tvf_randev:any_event_at_day_chance";
  function resetDefault() {
    world.setDynamicProperty(propId, anyEventAtDayChanceDefault);
  }
  function setValue(value) {
    world.setDynamicProperty(propId, value);
  }
  function getValue() {
    if (world.getDynamicProperty(propId) == undefined) return undefined;
    const value = world.getDynamicProperty(propId);
    return value;
  }
  AnyEventAtDayChance.resetDefault = resetDefault;
  AnyEventAtDayChance.setValue = setValue;
  AnyEventAtDayChance.getValue = getValue;
})(AnyEventAtDayChance || (AnyEventAtDayChance = {}));
export function resetAllConfigs() {
  //обновит конфиги до дефолтных
  AllEventProp.update(eventsDefault);
  CurrentEventProp.update(currentEventDefault);
  AnyEventAtDayChance.resetDefault();
  //если загрузит аддон не в 0 день, обновит таймеры отностельно текущего дня
  let data = AllEventProp.getProp();
  data.meteorite.nextFallDay = world.getDay() + 0;
  data.black_hole.nextDay = world.getDay() + 3;
  data.tornado.nextDay = world.getDay() + 1;
  AllEventProp.update(data);
}
export function resetAllConfigs_but_SaveSheldued() {
  const oldData = AllEventProp.getProp();
  oldData.meteorite.nextFallDay;
  //обновит конфиги до дефолтных
  AllEventProp.update(eventsDefault);
  CurrentEventProp.update(currentEventDefault);
  AnyEventAtDayChance.resetDefault();
  if (oldData == undefined || oldData == {}) return;
  //оставит текущее значение для не рандомных ивентов
  let data = AllEventProp.getProp();
  data.meteorite.nextFallDay = oldData.meteorite.nextFallDay;
  data.black_hole.nextDay = oldData.black_hole.nextDay;
  data.tornado.nextDay = oldData.tornado.nextDay;
  AllEventProp.update(data);
}
