import * as ui from "@minecraft/server-ui";
import { world, system } from "@minecraft/server";
import { gauntletAbilityMappings, upgradeCosts } from "./abilityMappings";

const buttonIconPaths = {
   back: "textures/octovon/eg/forms/button_icon_back",
   exit: "textures/octovon/eg/forms/button_icon_exit",
   upgrade: "textures/octovon/eg/forms/button_icon_upgrade"
}

export function openSettingsMenu(player) {
   const form = new ui.ModalFormData().title({ rawtext: [{ translate: `forms.settingsMenu.title` }] });
   const pvpDamageScalling = world.getDynamicProperty("oct_eg:pvpDamageScallingPercent");

   form.slider(
      { rawtext: [{ translate: `forms.settingsMenu.pvpDamageScalling` }] },
      0,
      100,
      10,
      pvpDamageScalling,
   );
   form.show(player).then(result => {
      if (result.canceled) return;
      else {
         const newValue = result.formValues[0];
         world.setDynamicProperty("oct_eg:pvpDamageScallingPercent", newValue);
         world.sendMessage(`pvpDamageScalling §2SET§r: ${newValue}`);
      }
   });
}

export function openUpgradeMenu(player, gauntletTypeId = "oct_eg:hydro_gauntlet") {

   const gauntlet = player.gauntletManager.gauntlets.get(gauntletTypeId);
   const gauntletData = { ...gauntlet.upgradeStages };
   const abilityMappings = { ...gauntletAbilityMappings[gauntletTypeId] };

   const form = new ui.ActionFormData().title({ rawtext: [{ translate: `forms.gauntletUpgradeMenu.title` }] });

   form.body(
      {
         rawtext: [
            {
               translate: `forms.body.frame`, "with": {
                  "rawtext": [
                     { text: "\n" },
                     {
                        translate: `forms.gauntletUpgradeMenu.body.main`, "with": {
                           "rawtext": [
                              { text: "\n" },
                              { translate: `forms.gauntletUpgradeMenu.element_name.${abilityMappings.element_key}` },
                              { text: `${abilityMappings.color_key}` },
                           ]
                        }
                     }
                  ]
               }
            }
         ]
      }
   );

   form.button({ // Passive
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.button.select_ability.passive`, with: {
            "rawtext": [
               { text: "\n" },
               { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.passive` },
               (gauntletData.passive > 0 ? { translate: `forms.gauntletUpgradeMenu.button.select_ability.upgrade_value`, with: [`${gauntletData.passive}`] } : {}),
            ]
         }
      }]
   }, abilityMappings.icon_paths.passive);

   form.button({ // Primary
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.button.select_ability.primary`, with: {
            "rawtext": [
               { text: "\n" },
               { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.primary` },
               (gauntletData.primary > 0 ? { translate: `forms.gauntletUpgradeMenu.button.select_ability.upgrade_value`, with: [`${gauntletData.primary}`] } : {}),
            ]
         }
      }]
   }, abilityMappings.icon_paths.primary);

   form.button({ // Skill 1
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.button.select_ability.skill1`, with: {
            "rawtext": [
               { text: "\n" },
               { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.skill1` },
               (gauntletData.skill1 > 0 ? { translate: `forms.gauntletUpgradeMenu.button.select_ability.upgrade_value`, with: [`${gauntletData.skill1}`] } : {}),
            ]
         }
      }]
   }, abilityMappings.icon_paths.skill1);

   form.button({ // Skill 2
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.button.select_ability.skill2`, with: {
            "rawtext": [
               { text: "\n" },
               { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.skill2` },
               (gauntletData.skill2 > 0 ? { translate: `forms.gauntletUpgradeMenu.button.select_ability.upgrade_value`, with: [`${gauntletData.skill2}`] } : {}),
            ]
         }
      }]
   }, abilityMappings.icon_paths.skill2);

   form.button({ // Skill 3
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.button.select_ability.skill3`, with: {
            "rawtext": [
               { text: "\n" },
               { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.skill3` },
               (gauntletData.skill3 > 0 ? { translate: `forms.gauntletUpgradeMenu.button.select_ability.upgrade_value`, with: [`${gauntletData.skill3}`] } : {}),
            ]
         }
      }]
   }, abilityMappings.icon_paths.skill3);

   form.button({ rawtext: [{ translate: "forms.button.exit" }] }, buttonIconPaths["exit"]);

   form.show(player).then(result => {
      if (result.canceled || result.selection === 5) return;

      let abilityKey = undefined;
      switch (result.selection) {
         case 0:
            abilityKey = "passive";
            break;
         case 1:
            abilityKey = "primary";
            break;
         case 2:
            abilityKey = "skill1";
            break;
         case 3:
            abilityKey = "skill2";
            break;
         case 4:
            abilityKey = "skill3";
            break;
      }
      openAbilityUpgradeMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey);
      return;
   });

}

function openAbilityUpgradeMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey) {
   const abilityData = { ...abilityMappings.abilities[abilityKey] };
   const currentLevel = gauntlet.upgradeStages[abilityKey];

   const upgradeCost = upgradeCosts[currentLevel];
   const upgradeItem = abilityMappings.required_shard_TypeId;
   const heldUpgradeItems = getItemCount(player, upgradeItem);

   const form = new ui.ActionFormData().title({ rawtext: [{ translate: `forms.gauntletUpgradeMenu.title` }] });

   // Compile stats and upgrade deltas
   const compiledStats = {};
   const upgradeDelta = {};

   // Process base and current stages
   for (let i = 0; i <= currentLevel; i++) {
      for (const stat of abilityData.stages[i]?.stats ?? []) {
         const { stat: name, value, added_value, symbol = "" } = stat;

         if (!(name in compiledStats)) {
            compiledStats[name] = { value: 0, symbol: "" };
            upgradeDelta[name] = 0;
         }

         if (value !== undefined && i === 0) {
            compiledStats[name].value = value;
            compiledStats[name].symbol = symbol;
         } else if (added_value !== undefined) {
            compiledStats[name].value += added_value;
         } else if (value !== undefined) {
            compiledStats[name].value = value;
         }
      }
   }

   // Process next stage deltas
   const nextStageStats = abilityData.stages[currentLevel + 1]?.stats ?? [];
   for (const { stat: name, added_value, value, symbol = "" } of nextStageStats) {
      if (!(name in compiledStats)) compiledStats[name] = { value: 0, symbol };
      const current = compiledStats[name].value ?? 0;
      const deltaValue = added_value ?? (value !== undefined ? value - current : 0);
      upgradeDelta[name] = { value: deltaValue, symbol };
   }

   // Render stat entries
   const statRawtextEntries = Object.entries(compiledStats)
      .filter(([name, { value }]) => { return value !== 0 || (upgradeDelta[name]?.value ?? 0) !== 0; }) // 👈 Filter out inactive stats
      .map(([name, { value, symbol }]) => {
         const delta = upgradeDelta[name];
         const deltaEntry = delta?.value
            ? {
               translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.stats_list.new_value`,
               with: [
                  delta.value > 0 ? "+" : "-",
                  `${Math.abs(delta.value)}`,
                  delta.symbol ?? ""
               ]
            }
            : { text: "" };

         return {
            translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.stats_list.stat`,
            with: {
               rawtext: [
                  { text: `\n` },
                  { text: name },
                  { text: `${value ? value : "--"}` },
                  deltaEntry,
                  { text: `${value ? symbol ?? "" : ""}` }
               ]
            }
         };
      });

   // Collect and render effects
   const effectstatRawtextEntries = [];
   for (let i = 0; i <= currentLevel; i++) {
      for (const effect of abilityData.stages[i]?.effects ?? []) {
         const formattedEffect = effect.replace(/§r/g, "§r§u").replace(/%/g, "%%");
         effectstatRawtextEntries.push({
            translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.effect_list.effect`,
            with: {
               rawtext: [
                  { text: "\n" },
                  { text: `§u ${formattedEffect}` }
               ]
            }
         });
      }
   }
   const nextStageEffects = abilityData.stages[currentLevel + 1]?.effects ?? [];
   if (nextStageEffects.length > 0) {
      for (const effect of nextStageEffects) {
         const formattedEffect = effect.replace(/§r/g, "§r§q").replace(/%/g, "%%");
         effectstatRawtextEntries.push({
            translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.effect_list.effect`,
            with: {
               rawtext: [
                  { text: "\n" },
                  { text: `§q ${formattedEffect}` }
               ]
            }
         });
      }
   }

   let formatedInfo = abilityData.info
      .replace(/§r/g, "§r§o§7")
      .replace(/%/g, "%%");

   const bodyText = {
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.main`,
         with: {
            rawtext: [
               { text: `\n` },
               { translate: `forms.divider`, with: [``] },
               {
                  translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.ability_name`,
                  with: {
                     rawtext: [
                        { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.${abilityKey}` },
                        { text: `${currentLevel}` },
                        (currentLevel < 3 ?
                           { text: ` -> §q+${currentLevel + 1}` }
                           : {}
                        ),
                     ]
                  }
               },
               { translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.ability_info`, with: [`${formatedInfo}`] },
               {
                  rawtext: statRawtextEntries.length > 0 ? statRawtextEntries : [{ text: `` }]
               },
               {
                  rawtext: effectstatRawtextEntries.length > 0 ? effectstatRawtextEntries : [{ text: `` }]
               },
               (
                  currentLevel >= 3
                     ? { text: `` }
                     : {
                        translate: `forms.gauntletUpgradeMenu.ability_upgrade.body.upgrade_cost`, with: {
                           rawtext: [
                              { text: "\n" },
                              { translate: `item.${upgradeItem}.name` },
                              { text: `${heldUpgradeItems}` },
                              { text: `${upgradeCost}` },
                              { text: `${heldUpgradeItems >= upgradeCost ? `§q` : `§c`}` },
                              { translate: `forms.divider`, with: [``] },
                           ]
                        }
                     }
               ),
            ]
         }
      }]
   };

   form.body({
      rawtext: [{
         translate: `forms.body.frame`, with: {
            rawtext: [
               { text: "\n" },
               bodyText
            ]
         }
      }]
   });


   if (currentLevel < 3) {
      if (heldUpgradeItems >= upgradeCost) {
         form.button({
            rawtext: [{
               translate: `forms.gauntletUpgradeMenu.button.upgrade_ability.able`, with: {
                  rawtext: [
                     { text: "\n" },
                     { text: `${heldUpgradeItems}` },
                     { text: `${upgradeCost}` },
                     { text: `${heldUpgradeItems >= upgradeCost ? `§q` : `§c`}` },
                  ]
               }
            }]
         }, buttonIconPaths[`upgrade`]);
      } else {
         form.button({
            rawtext: [{ translate: `forms.gauntletUpgradeMenu.button.upgrade_ability.not_able`, with: { rawtext: [{ text: "\n" }] } }]
         }, buttonIconPaths[`upgrade`]);
      }
   }

   form.button({ rawtext: [{ translate: "forms.button.back" }] }, buttonIconPaths["back"]);
   form.button({ rawtext: [{ translate: "forms.button.exit" }] }, buttonIconPaths["exit"]);

   form.show(player).then(result => {
      if (result.canceled || result.selection === undefined) return;

      const buttons = [];
      if (currentLevel < 3) {
         buttons.push("upgrade"); // index 0
      }
      buttons.push("back");  // index 1 if upgrade was added, 0 if not
      buttons.push("exit");  // index 2 if upgrade was added, 1 if not

      switch (buttons[result.selection]) {
         case "upgrade":
            try {
               // Count items again
               // const secondItemCountCheck = 99;
               const secondItemCountCheck = getItemCount(player, upgradeItem);
               if (secondItemCountCheck >= upgradeCost) {
                  // Upgrade the ability
                  const newLevel = currentLevel + 1;
                  gauntlet.upgradeStages[abilityKey] = newLevel;

                  // Long term save
                  player.setDynamicProperty(`oct_eg:ul.${abilityMappings.element_key}.${abilityKey}`, newLevel);

                  // Remove the upgrade items from the player's inventory
                  player.runCommand(`clear @s ${upgradeItem} 0 ${upgradeCost}`);

                  // Message and effects
                  world.sendMessage({
                     rawtext: [{
                        translate: `message.oct_eg.player_upgraded_ability.success`, with: {
                           rawtext: [
                              { text: `${player.name}` },
                              { translate: `forms.gauntletUpgradeMenu.ability_name.${abilityMappings.element_key}.${abilityKey}` },
                              { text: `${currentLevel + 1}` },
                              { text: `${abilityMappings.color_key}` },

                           ]
                        }
                     }]
                  });
                  player.dimension.playSound('random.levelup', player.location);

                  // Re-open the menu
                  openAbilityUpgradeMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey);

               } else openUpgradeFailedMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey, upgradeItem);

            } catch (e) {
               //world.sendMessage(`§cError while upgrading ability: ${e}`);
            }
            break;

         case "back":
            openUpgradeMenu(player, gauntletTypeId);
            break;

         case "exit":
         default:
            return;
      }
   });
}

function getItemCount(player, itemTypeId) {
   const inventory = player.getComponent("inventory").container;

   let itemAmount = 0;
   for (let i = 0; i < inventory.size; i++) {
      const stack = inventory.getItem(i);
      if (stack?.typeId === itemTypeId) {
         itemAmount += stack.amount;
      }
   }

   return itemAmount;
}

function openUpgradeFailedMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey, upgradeItem) {
   const form = new ui.MessageFormData().title({ rawtext: [{ translate: `forms.gauntletUpgradeMenu.title` }] });

   form.body({
      rawtext: [{
         translate: `forms.gauntletUpgradeMenu.ability_upgrade.deny`, with: {
            rawtext: [{ translate: `item.${upgradeItem}.name` }]
         }
      }]
   });
   form.button1({ rawtext: [{ translate: "forms.button.back" }] });
   form.button2({ rawtext: [{ translate: "forms.button.exit" }] });

   player.playSound('extinguish.candle');

   form.show(player).then((response) => {
      if (response.selection === 0) {
         openAbilityUpgradeMenu(player, gauntletTypeId, gauntlet, abilityMappings, abilityKey);
      }
   });
}