import { system, world, GameMode } from "@minecraft/server";
import {
  neutralMobs,
  hostileMobs,
  goodMobs,
  evilMobs,
  villagers,
  xpValues,
  bossMobs,
  combinedMobs,
} from "../variables";
import { TIER1MAX, TIER2MAX, TIER3MAX, TIERPARAGONMAX } from "../constants";
export var evilXP = new Map();
export var checks = new Map();
export var evilTier = new Map();
export var evilXPChecks = new Map();
export var reverseEvilXPChecks = new Map();

// Checks if the player is evil; if not, don't run
export function isDisabled(player) {
  return (
    player.hasTag("evil") ||
    player.hasTag("neutral") ||
    player.getGameMode() == GameMode.creative ||
    player.getGameMode() == GameMode.spectator
  );
}

// Initializes the player's data from tags
export function initializePlayerData(player) {
  try {
    const tags = player.getTags();
    let xpTag = null;
    let tierTag = null;

    // Search for relevant tags
    for (const tag of tags) {
      if (tag.startsWith("evilXP_")) {
        xpTag = tag;
      } else if (tag.startsWith("evil_tier_")) {
        tierTag = tag;
      }
    }

    // Restore XP from the tag or default to 0
    if (xpTag) {
      const xp = parseInt(xpTag.split("_")[1], 10);
      evilXP.set(player.id, xp);
    } else if (!evilXP.has(player.id)) {
      evilXP.set(player.id, 0); // Only set default if no prior value exists
    }

    // Restore Tier from the tag or default to 1
    if (tierTag) {
      const playerTier = parseInt(tierTag.split("_")[2], 10);
      evilTier.set(player.id, playerTier);
    } else if (!evilTier.has(player.id)) {
      evilTier.set(player.id, 1); // Only set default if no prior value exists
    }
  } catch (error) {
    console.error(`Error initializing player data: ${error}`);
  }
}

// Updates the player's tags to store XP and tier
export function updatePlayerTags(player) {
  const xp = evilXP.get(player.id) || 0;
  const playerTier = evilTier.get(player.id) || 1;

  // Remove old tags
  player.getTags().forEach((tag) => {
    if (tag.startsWith("evilXP_") || tag.startsWith("evil_tier_")) {
      player.removeTag(tag);
    }
  });

  // Add updated tags
  player.addTag(`evilXP_${xp}`);
  player.addTag(`evil_tier_${playerTier}`);
}

export function upgradePlayerTier(player) {
  try {
    if (!player) return;
    let currentTier = evilTier.get(player.id) || 1;
    let playerEvilXP = evilXP.get(player.id) || 0;
    if (currentTier >= 3) {
      console.error(`§cYou have already reached the maximum tier.`);
      return;
    }
    player.runCommand(`playsound float_ad.level_up_evil "${player.name}"`);
    currentTier += 1;
    playerEvilXP = 0;

    evilTier.set(player.id, currentTier);
    evilXP.set(player.id, playerEvilXP);

    updatePlayerTags(player);
    player.removeTag(`check_item_evil_${currentTier}_helmet`);
    if (currentTier < 3) {
      player.addTag(`check_item_evil_${currentTier + 1}_helmet`);
    }
  } catch (error) {
    console.error(`Error upgrading player tier: ${error}`);
  }
}

// Clears tracking checks
export function clearTrackCheck(playerId) {
  const checkId = evilXPChecks.get(playerId);
  if (checkId !== undefined) {
    checks.delete(checkId);
    evilXPChecks.delete(playerId);
    reverseEvilXPChecks.delete(checkId);
  }
}

// Updates player's progress and tags
export function progress(player, amount) {
  if (player !== undefined) {
    // Retrieve the evilXP value from the player's tag
    const tags = player.getTags();
    let tagXP = 0;

    for (const tag of tags) {
      if (tag.startsWith("evilXP_")) {
        tagXP = parseInt(tag.split("_")[1], 10) || 0;
        break;
      }
    }

    // Use the tagXP value to update the evilXP map
    evilXP.set(player.id, tagXP);

    let playerevilXP = evilXP.get(player.id) || 0;
    let currentTier = evilTier.get(player.id) || 1;

    // Calculate the maxXP based on the current tier
    let maxXP;
    if (currentTier == 1) maxXP = TIER1MAX;
    else if (currentTier == 2) maxXP = TIER2MAX;
    else if (currentTier == 3) maxXP = TIER3MAX;
    else maxXP = TIERPARAGONMAX;

    // Ensure XP does not go below 0 and prevent tier downgrade
    if (amount < 0 && playerevilXP + amount < 0) {
      amount = -playerevilXP;
    }

    // Update the XP and handle level-ups
    playerevilXP = Math.max(0, playerevilXP + amount);
    if (currentTier == 3) {
      return;
    }
    if (playerevilXP >= maxXP) {
      playerevilXP = maxXP;
      player.sendMessage(
        "§aYou have reached the maximum level for this tier." +
          "§r\n§aYou can now upgrade to the next tier." +
          "§r\n§aCraft the next tier Horns at the hub."
      );

      // Play level up sound based on affiliation
      if (player.hasTag("evil")) {
        player.runCommand(`playsound float_ad.level_up_evil "${player.name}"`);
      } else if (player.hasTag("good")) {
        player.runCommand(`playsound float_ad.level_up_good "${player.name}"`);
      }

      //upgradePlayerTier(player);
    }

    // Update the maps and tags
    evilXP.set(player.id, playerevilXP);
    updatePlayerTags(player);
    displayEvilXP(player, playerevilXP);
  }
}

// Displays the evil XP bar
export function displayEvilXP(player, level) {
  try {
    const currentTier = evilTier.get(player.id);
    let maxXP;
    if (currentTier == 1) maxXP = 500;
    else if (currentTier == 2) maxXP = 1000;
    else if (currentTier == 3) maxXP = 2000;
    else maxXP = 2000;

    const progress = Math.min(level / maxXP, 1);

    const totalSquares = 30;
    const filledSquares = Math.round(progress * totalSquares);
    const emptySquares = totalSquares - filledSquares;

    const xpBar = `§c${"⬛".repeat(filledSquares)}§7${"⬜".repeat(emptySquares)}`;
    if (currentTier == 3) {
      player.onScreenDisplay.setActionBar(`§l§4Evil XP§r\n§cCurrent Max Demon Tier`);
    } else {
      player.onScreenDisplay.setActionBar(`§l§4Evil XP§r\n${xpBar}\n§rAmount: ${level}/${maxXP}`);
    }
  } catch (error) {
    console.error(`Error displaying XP bar: ${error}`);
  }
}
// Handles XP changes when a mob is killed
export function mobKilled(mob, location, player, deadEntity) {
  if (!combinedMobs.includes(mob)) {
    return; // Do nothing if the mob is not in the combinedMobs list
  }

  if (hostileMobs.includes(mob)) {
    return; // Do nothing if the mob is in the hostileMobs array
  }
  if (villagers.includes(mob)) {
    return; // Do nothing if the mob is in the villagers array
  }

  let amount = xpValues[mob];
  let isGain = false;

  if (mob === "float_ad:wisp" || mob === "float_ad:elemental_golem") {
    const state = deadEntity.getProperty("float_ad:state");
    amount = xpValues[mob];
    if (state == 0 || state == 1) {
      isGain = true;
    } else if (state == 2) {
      isGain = false;
    } else {
      amount = 0;
    }
  } else {
    isGain = neutralMobs.includes(mob) || goodMobs.includes(mob) || bossMobs.includes(mob);
  }

  if (amount !== 0) {
    const particleEffect = isGain ? `xp_gain_${Math.abs(amount)}` : `xp_drain_${Math.abs(amount)}`;
    player.runCommand(`particle float_ad:${particleEffect} ${location.x} ${location.y} ${location.z}`);
    progress(player, isGain ? amount : -amount);
  }
}
