import { world, system, ItemStack, BlockPermutation } from "@minecraft/server";
import { ModalFormData, ActionFormData } from "@minecraft/server-ui";
import {
  AllEventProp,
  CurrentEventProp,
  AnyEventAtDayChance,
  anyPlayerNotUnderground,
  anyPlayerInDimension,
  resetAllConfigs_but_SaveSheldued,
} from "./utilities";
import { itemUseOnBlockCraftsConfig } from "./configs/recipesConfig";
import { summonBlackHole, summonTornado, randomInteger } from "./scheldules";
import { dayTimeRandomIntervals as rInterval } from "./configs/eventConfig";
// black hole in bottle crafts
export function itemUseOn_recipes() {
  world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
    if (!event.isFirstEvent) return;
    const recipeData = itemUseOnBlockCraftsConfig.resipes.find(
      (recipe) =>
        event.itemStack &&
        recipe.blockId === event.block.typeId &&
        (typeof recipe.input === "string"
          ? recipe.input === event.itemStack.typeId
          : recipe.input.includes(event.itemStack.typeId))
    );
    if (recipeData == undefined) return;
    const player = event.player;
    system.run(() => {
      player.dimension.playSound("beacon.deactivate", event.block.location, {
        pitch: 3,
      });
      player.dimension.spawnParticle(
        "tvf_randev:black_hole_in_bottle_craft",
        event.block.center()
      );
    });
    const oldAmount = event.itemStack.amount;
    const fullStackSize = event.itemStack.maxAmount;
    let newAmount = oldAmount * recipeData.output_multiplier;
    if (newAmount > fullStackSize) {
      let numberOfFullStacks = Math.floor(newAmount / fullStackSize);
      newAmount = newAmount % fullStackSize;
      if (newAmount == 0) {
        numberOfFullStacks -= 1;
        newAmount = fullStackSize;
      }
      const fullStack = new ItemStack(recipeData.output, fullStackSize);
      for (let i = 0; i < numberOfFullStacks; i++) {
        system.waitTicks(1).then(() => {
          system.run(() => {
            player.dimension.spawnItem(fullStack, player.location);
          });
        });
      }
    }
    const newItem = new ItemStack(
      Array.isArray(recipeData.output)
        ? recipeData.output[
            Math.floor(Math.random() * recipeData.output.length)
          ]
        : recipeData.output,
      newAmount
    );
    system.run(() => {
      player.getComponent("equippable").setEquipment("Mainhand", newItem);
    });
  });
}
//fabric of reality
export function itemUse_fabricOfReality(itemId) {
  world.afterEvents.itemUse.subscribe((event) => {
    // Проверяем, что использован нужный предмет
    if (event.itemStack.typeId !== itemId) return;
    const player = event.source;
    const buttonData = AllEventProp.getSheet_translateKey_Available();
    const newEventData = AllEventProp.getProp();
    // Создаем основную форму
    const mainForm = new ModalFormData()
      .title({
        translate: "tvf_randev.fabricofreality.title",
      })
      .slider(
        {
          translate: "tvf_randev.fabricofreality.slidebar.anyeventchance",
        },
        0,
        100,
        {
          defaultValue: AnyEventAtDayChance.getValue(),
          step: 1,
          tooltip: "Chance of any event at day",
        }
      );
    // Добавляем переключатели для каждого события
    for (const buttonId in buttonData) {
      mainForm.toggle(
        {
          translate: buttonData[buttonId].translateKey,
        },
        {
          defaultValue: buttonData[buttonId].is_available,
        }
      );
    }
    mainForm.submitButton({
      translate: "tvf_randev.fabricofreality.submitButton",
    });
    // Показываем основную форму
    mainForm.show(player).then(handleMainFormResponse);
    function handleMainFormResponse(response) {
      if (response.canceled) {
        showErrorMessage(player);
        return;
      }
      // Создаем форму подтверждения
      const confirmationForm = new ActionFormData()
        .title({
          translate: "tvf_randev.fabricofreality.title",
        })
        .button({
          translate:
            "tvf_randev.fabricofreality.confirmationForm.button.resettodefault",
        })
        .button({
          translate: "tvf_randev.fabricofreality.confirmationForm.button.save",
        })
        .body("\n\n\n\n");
      confirmationForm.show(player).then(handleConfirmationResponse);
      function handleConfirmationResponse(saverResponse) {
        if (saverResponse.canceled) {
          showErrorMessage(player);
          return;
        }
        if (saverResponse.selection === 0) {
          // Сброс к значениям по умолчанию
          resetToDefault(player);
        } else if (saverResponse.selection === 1) {
          // Сохранение изменений
          saveChanges(response.formValues, player);
        }
      }
    }
    function resetToDefault(player) {
      resetAllConfigs_but_SaveSheldued();
      player.sendMessage({
        translate: "tvf_randev.fabricofreality.message.reset_default",
      });
      player.playSound("block.cartography_table.use");
    }
    function saveChanges(formValues, player) {
      // Обновляем доступность событий
      let i = 1; // Первый элемент (0) - это слайдер
      for (const buttonId in buttonData) {
        const oldAvailable = newEventData[buttonId].is_available;
        const newAvailable = formValues[i];
        newEventData[buttonId].is_available = newAvailable;
        //Если это событие со своим расписанием, то обновить расписание с текущего дня
        if (
          newEventData[buttonId].is_random == false &&
          newAvailable == true &&
          oldAvailable == false
        ) {
          handleNoRandomEvent(newEventData[buttonId]);
        }
        // Если текущее событие было отключено, сбрасываем его
        if (
          !newEventData[buttonId].is_available &&
          CurrentEventProp.getProp().id === newEventData[buttonId].id
        ) {
          CurrentEventProp.update({});
        }
        i++;
      }
      // Сохраняем изменения
      AllEventProp.update(newEventData);
      AnyEventAtDayChance.setValue(formValues[0]);
      player.sendMessage({
        translate: "tvf_randev.fabricofreality.message.save_complete",
      });
      player.playSound("block.cartography_table.use");
    }
    //
    function handleNoRandomEvent(event) {
      if (
        event.hasOwnProperty("nextFallDay") &&
        event.hasOwnProperty("nextFallTime")
      ) {
        event.nextFallDay =
          world.getDay() +
          randomInteger(
            rInterval.meteorite.natural.day.min,
            rInterval.meteorite.natural.day.max
          );
        event.nextFallTime =
          world.getDay() +
          randomInteger(
            rInterval.meteorite.natural.time.min,
            rInterval.meteorite.natural.time.max
          );
      } else if (
        event.hasOwnProperty("nextDay") &&
        event.hasOwnProperty("nextTime")
      ) {
        if (event.id == "tornado") {
          event.nextDay =
            world.getDay() +
            randomInteger(
              rInterval.tornado.natural.day.min,
              rInterval.tornado.natural.day.max
            );
          event.nextTime =
            world.getDay() +
            randomInteger(
              rInterval.tornado.natural.time.min,
              rInterval.tornado.natural.time.max
            );
        } else if (event.id == "black_hole") {
          event.nextDay =
            world.getDay() +
            randomInteger(
              rInterval.black_hole.natural.day.min,
              rInterval.black_hole.natural.day.max
            );
          event.nextTime =
            world.getDay() +
            randomInteger(
              rInterval.black_hole.natural.time.min,
              rInterval.black_hole.natural.time.max
            );
        }
      }
    }
    function showErrorMessage(player) {
      player.sendMessage({
        translate: "tvf_randev.fabricofreality.message.save_error",
      });
      player.playSound("block.false_permissions");
    }
  });
}
//test item
export function itemUse_TestItem(itemId) {
  //триггер
  world.afterEvents.itemUse.subscribe((event) => {
    if (event.itemStack.typeId != itemId) return;
    const player = event.source;
    formsMain(player);
  });
  //основная форма
  function formsMain(player) {
    let buttonData = AllEventProp.getSheet_translateKey_Available();
    let newEventData = AllEventProp.getProp();
    const form = new ActionFormData()
      .title({
        translate: "tvf_randev.creativefabric.title",
      })
      .body(getCurrentEventString(CurrentEventProp.getProp()))
      .button({
        translate: "tvf_randev.creativefabric.button.config",
      })
      .button({
        translate: "tvf_randev.creativefabric.button.summon_event_menu",
      });
    form.show(player).then(handleMainFormResponse);
    function handleMainFormResponse(response) {
      if (response.canceled) return;
      const index = response.selection;
      //показать Config
      if (index == 0) {
        const configForm = new ActionFormData()
          .title({
            translate: "tvf_randev.creativefabric.title",
          })
          .body(getEventsInfoString(AllEventProp.getProp()));
        configForm.show(player).then(handleConfigFormResponse);
        return;
      }
      //summon menu
      if (index == 1) {
        const summonForm = new ActionFormData()
          .title({
            translate: "tvf_randev.creativefabric.title",
          })
          .body({
            translate: "tvf_randev.creativefabric.summonmenu.body",
          });
        for (const buttonId in buttonData) {
          summonForm.button({
            translate: buttonData[buttonId].translateKey,
          });
        }
        summonForm.show(player).then(handleSummonFormResponse);
        return;
      }
    }
    function handleSummonFormResponse(response) {
      //возвращает на главную
      if (response.canceled) {
        formsMain(player);
        return;
      }
      const index = response.selection;
      //вызывает ивент в зависимости от выбора
      let i = 0;
      for (const buttonId in buttonData) {
        if (i == index) {
          if (newEventData[buttonId].is_available == true) {
            if (anyPlayerInDimension(newEventData[buttonId].dimension)) {
              if (
                (newEventData[buttonId].only_on_surface == true &&
                  anyPlayerNotUnderground() == true) ||
                newEventData[buttonId].only_on_surface == false
              ) {
                player.sendMessage({
                  translate: "tvf_randev.creativefabric.message.succsess",
                });
                if (newEventData[buttonId].is_random == true) {
                  CurrentEventProp.update({
                    id: buttonId,
                    status: "is_planned",
                    timer: 0,
                    maxDuration: newEventData[buttonId].maxDuration,
                    planned_tick: world.getTimeOfDay() + 20,
                    dimension: newEventData[buttonId].dimension,
                    only_on_surface: newEventData[buttonId].only_on_surface,
                    forcedEnd: false,
                  });
                } else {
                  if (buttonId == "tornado") {
                    summonTornado(player);
                  }
                  if (buttonId == "black_hole") {
                    summonBlackHole(player);
                  }
                  if (buttonId == "meteorite") {
                    player.dimension.spawnEntity("tvf_randev:meteor", {
                      x: player.location.x,
                      y: player.location.y + 30,
                      z: player.location.z,
                    });
                  }
                }
              } else
                player.sendMessage({
                  translate:
                    "tvf_randev.creativefabric.message.error.underground",
                });
            } else
              player.sendMessage({
                translate: "tvf_randev.creativefabric.message.error.dimension",
              });
          } else
            player.sendMessage({
              translate: "tvf_randev.creativefabric.message.error.available",
            });
        }
        i++;
      }
    }
    function handleConfigFormResponse(response) {
      if (response.canceled) {
        formsMain(player);
      }
    }
  }
}
//tnt black hole activate
world.afterEvents.playerInteractWithBlock.subscribe((event) => {
  const block = event.block;
  const item = event.itemStack;
  if (
    block.typeId == "tvf_randev:black_hole_tnt" &&
    item.typeId == "minecraft:flint_and_steel"
  ) {
    block.setPermutation(BlockPermutation.resolve("minecraft:air"));
    block.dimension.spawnEntity("tvf_randev:blackhole_tnt", {
      x: block.location.x + 0.5,
      y: block.location.y + 0,
      z: block.location.z + 0.5,
    });
  }
});
//white hole placing
world.afterEvents.playerPlaceBlock.subscribe((event) => {
  if (event.block.typeId == "tvf_randev:white_hole_in_bottle") {
    const block = event.block;
    block.dimension.spawnEntity("tvf_randev:white_hole", {
      x: block.location.x + 0.5,
      y: block.location.y + 3,
      z: block.location.z + 0.5,
    });
    block.setPermutation(BlockPermutation.resolve("tvf_randev:vacuum_bottle"));
  }
});
//инфо всякое
function getCurrentEventString(data) {
  const currentEvent = data; // или получение текущего события
  const anyEventChance = AnyEventAtDayChance.getValue();
  // Создаем строку с цветовыми кодами
  let message = `Daily Event Chance: ${anyEventChance}%%\n`;
  message += "Day: " + world.getDay() + " ";
  message += "Time: " + world.getTimeOfDay() + "\n";
  message += "§6§l      === Current Event ===§r\n";
  message += "§7--------------------------------§r\n";
  // ID
  message += `§eID: §r${currentEvent.id ? currentEvent.id : "§cnone§r"}\n`;
  // Status
  message += `§aStatus: §r${
    currentEvent.status ? currentEvent.status : "§cnone§r"
  }\n`;
  // Timer
  message += `§bTimer: §r${
    currentEvent.timer !== undefined ? currentEvent.timer : "§cnone§r"
  } / §r${
    currentEvent.maxDuration !== undefined
      ? currentEvent.maxDuration
      : "§cnone§r"
  }\n`;
  //forsed end
  message += `§bForced end: §r${
    currentEvent.forcedEnd ? "§atrue§r" : "§cfalse§r"
  }\n`;
  // Planned tick
  message += `§dPlanned tick: §r${
    currentEvent.planned_tick !== undefined
      ? currentEvent.planned_tick
      : "§cnone§r"
  }\n`;
  // Dimension tick
  message += `§dDimension: §r${
    currentEvent.dimension !== undefined ? currentEvent.dimension : "§cnone§r"
  }\n`;
  // Only Surface tick
  message += `§dOnly Surface: §r${
    currentEvent.only_on_surface ? "§atrue§r" : "§cfalse§r"
  }`;
  return message;
}
function getEventsInfoString(data) {
  const events = data;
  // Создаем заголовок таблицы
  let message = "§6§l       === Events Info ===§r\n";
  message += "§7--------------------------------§r\n";
  // Добавляем информацию о каждом рандомном событии
  for (const event of Object.values(events)) {
    if (event.is_random == true) {
      // Первая строка - только ID
      message += `§eID: ${event.id}§r\n`;
      // Вторая строка - все остальные свойства
      let propsLine = "";
      propsLine += ` §bWeight: §r${event.w}§r,\n`;
      //propsLine += ` §bRandom: ${event.is_random ? "§atrue§r" : "§cfalse§r"},\n`;
      propsLine += ` §bAvailable: ${
        event.is_available ? "§atrue§r" : "§cfalse§r"
      },\n`;
      propsLine += ` §bDimension: §r${event.dimension}§r,\n`;
      propsLine += ` §bOnly Surface: §r${
        event.only_on_surface ? "§atrue§r" : "§cfalse§r"
      },\n`;
      // Добавляем специальные свойства
      if ("nextDay" in event && "nextTime" in event) {
        propsLine += `, §dNext: day ${event.nextDay}, time ${event.nextTime}§r`;
      } else if ("nextFallDay" in event && "nextFallTime" in event) {
        propsLine += `, §dNext fall: day ${event.nextFallDay}, time ${event.nextFallTime}§r`;
      }
      message += propsLine + "\n";
    }
  }
  // Добавляем информацию о каждом НЕ рандомном событии
  message += "§6Special events have their own schedule:§r\n\n";
  for (const event of Object.values(events)) {
    if (event.is_random == false) {
      // Первая строка - только ID
      message += `§eID: ${event.id}§r\n`;
      // Вторая строка - все остальные свойства
      let propsLine = "";
      //propsLine += ` §aWeight: ${event.w}§r, `;
      //propsLine += ` §bRandom: ${event.is_random}§r,\n`;
      propsLine += ` §bAvailable: ${
        event.is_available ? "§atrue§r" : "§cfalse§r"
      },\n`;
      propsLine += ` §bDimension: §r${event.dimension}§r,\n`;
      propsLine += ` §bOnly Surface: §r${
        event.only_on_surface ? "§atrue§r" : "§cfalse§r"
      },\n`;
      // Добавляем специальные свойства
      if ("nextDay" in event && "nextTime" in event) {
        propsLine += ` §dNext: day ${event.nextDay}, time ${event.nextTime}§r`;
      } else if ("nextFallDay" in event && "nextFallTime" in event) {
        propsLine += ` §dNext fall: day ${event.nextFallDay}, time ${event.nextFallTime}§r`;
      }
      message += propsLine + "\n\n";
    }
  }
  return message;
}
