import { system, world, EntityComponentTypes } from '@minecraft/server';
import { ModalFormData, MessageFormData, ActionFormData} from '@minecraft/server-ui';
import { gunLoop } from './guns/main';
import { bulletEntityImpact } from './guns/bullet';
import 'components/lights';
import 'components/props';

const init = () => {
  autoRunTick();
  events();
};

const tick = () => {
  gunLoop();
};

const autoRunTick = () => {
  tick();
  const timeoutId = system.runTimeout(() => {
    try {
      system.clearRun(timeoutId);
      autoRunTick();
    } catch (error) {
      console.warn(error);
    }
  }, 2);
};
system.runInterval((tick) => {
  for (let player of world.getPlayers()) {
    player.runCommandAsync(`/execute at @s[tag=training] run function training/kitloot`);
    player.runCommandAsync(`/execute at @e[name=start,scores={count=1521..,randomborder=1}] run function royale/borderdamage1`);
    player.runCommandAsync(`/execute at @e[name=start,scores={count=1521..,randomborder=2}] run function royale/borderdamage2`);
    player.runCommandAsync(`/execute at @e[name=start,scores={count=1521..,randomborder=3}] run function royale/borderdamage3`);
    player.runCommandAsync(`/execute at @e[name=start,scores={count=1521..,randomborder=4}] run function royale/borderdamage4`);
    const health = player.getComponent(EntityComponentTypes.Health)?.currentValue;
    player.runCommandAsync(`/scoreboard players set @s health ${health}`);
      // Genera un número aleatorio entre 1 y 6
  let randomIndex = Math.floor(Math.random() * 6) + 1;
  // Asigna el valor a la variable de UI
  // (esto depende de cómo expongas bindings en tu pack)
  system.broadcastEvent("set_ui_variable", {
    name: "#random_bg_index",
    value: randomIndex
  });
  }
}, 20);
export function Score(player, objective) {
  try {
    return world.scoreboard
      .getObjective(objective)
      .getScore(player.scoreboardIdentity);
  } catch (error) {
    return 0;
  }
}
let menu_br=false;
let settings=false;
const events = () => {
  world.afterEvents.projectileHitEntity.subscribe(bulletEntityImpact);
  world.afterEvents.entityDie.subscribe((data) => {
    const entitya = data.deadEntity;
    const playera = data.damageSource;
    if (entitya.typeId == "minecraft:zombie") {
        playera.damagingEntity.runCommandAsync(`scoreboard players add @s points 1`)
        playera.damagingEntity.runCommandAsync(`playsound gun.gun @s`)
        playera.damagingEntity.runCommandAsync(`tellraw @s {"rawtext":[{"text":"§l§e1 Point"}]}`)
    };
    if (entitya.typeId == "minecraft:iron_golem") {
        playera.damagingEntity.runCommandAsync(`scoreboard players add @s points 4`)
        playera.damagingEntity.runCommandAsync(`playsound gun.gun @s`)
        playera.damagingEntity.runCommandAsync(`tellraw @s {"rawtext":[{"text":"§l§e4 Points"}]}`)
    };
    if (entitya.typeId == "converse:target") {
      playera.damagingEntity.runCommandAsync(`playsound gun.gun @s`)
  };
  });
  world.afterEvents.itemUse.subscribe((ev)=>{
    let player = ev.source;
    let item = ev.itemStack;
    if (item.typeId == "tef:stats") {
    system.run(() => {
                mostrarEstadisticas(player, world);
            });
        }
    if (item.typeId == "tef:next_player") {
    system.run(() => {
                Spectators(player);
            });
        }
    if (item.typeId == "tef:back_to_lobby") {
    player.runCommandAsync("tp @s 5 -55 0");
    player.runCommandAsync("clear");
    let alltags = player.getTags();
  for (const tag of alltags) {
    player.removeTag(tag);
  }
  player.runCommandAsync("camera @s clear");
        }
    if (item.typeId == "tef:reset_spectator") {
            player.runCommandAsync(`playsound note.bass @s`)
            system.run(() => {
                player.runCommandAsync(`function reset_spectator`);
            });
        }
    if (item.typeId == "converse:guide") {
            player.runCommandAsync(`playsound note.bass @s`)
            system.run(() => {
                guide(player);
            });
        }
    if (item.typeId == "converse:menu") {
            player.runCommandAsync(`playsound note.bass @s`)
            system.run(() => {
                Menu(player);
            });
        }
    if (item.typeId == "converse:menu_training") {
          player.runCommandAsync(`playsound note.bass @s`)
          system.run(() => {
            menu_training(player);
          });
      }
      if (item.typeId == "converse:stats") {
        player.runCommandAsync(`playsound note.bass @s`)
        system.run(() => {
          Stats(player);
        });
    }
      if (item.typeId == "converse:back_target") {
        player.runCommandAsync(`kill @e[type=converse:target]`);
        player.runCommandAsync(`replaceitem entity @s slot.hotbar 8 converse:menu_training 1 0 {"item_lock":{"mode":"lock_in_slot"}}`);
    }
  });
  world.afterEvents.entityHitEntity.subscribe(async event => {
  const player = event.damagingEntity
  const statue = event.hitEntity;
  if (statue.typeId == "converse:battle_royale_statue") {
    if (menu_br) {
    player.runCommandAsync(`tellraw @s {\"rawtext\":[{\"translate\":\"game.menu_used\"}]}`);
    player.runCommandAsync("playsound ui.button.click @s ~ ~ ~ 0.6 1.0");
    return;
  }  else {
    menu_br = true;
    player.runCommandAsync(`playsound note.bass @s`)
            system.run(() => {
                BattleRoyaleGame(player);
            });
          }
  }
  if (statue.typeId == "tef:settings") {
    if (settings) {
    player.runCommandAsync(`tellraw @s {\"rawtext\":[{\"translate\":\"game.menu_used\"}]}`);
    player.runCommandAsync("playsound ui.button.click @s ~ ~ ~ 0.6 1.0");
    return;
  }  else {
    settings = true;
    player.runCommandAsync(`playsound note.bass @s`)
            system.run(() => {
                MenuSettings(player);
            });
          }
  }

  });
  world.afterEvents.playerSpawn.subscribe(event => {
  const playerspec = event.player;
  const isInitial = event.initialSpawn;
  if (!isInitial && playerspec.hasTag("inMatch")) {
    playerspec.runCommandAsync("function royale/spectator")
  }
  if (isInitial) {
    world.runCommandAsync("setmaxplayers 12")
  }
  });
  world.afterEvents.playerLeave.subscribe(event => {
      world.getDimension("overworld").runCommandAsync("execute at @e[type=armor_stand,name=start,scores={games=1}] run function royale/counter_solo");
  });
};


export function Spectators(player){
  const vivos = world.getPlayers().filter(p => p.hasTag("inMatch"));
   const nombres = vivos.map(p => p.name);

  let i = new ModalFormData()
    i.title("game.mode_spectator")
    i.dropdown("game.select.player_spectate", nombres)
    i.toggle("game.show_stats", false)

  i.show(player).then(respuesta => {
    if (respuesta.canceled) return;

    const indice = respuesta.formValues[0];
    const verStats = respuesta.formValues[1];
    const objetivo = vivos[indice];
    let number = Score(objetivo,"players")
    let tags = player.getTags();
  for (const tag of tags) {
    player.removeTag(tag);
  }
  switch (number) {
    case 1:
      player.addTag("spectator_1")
      break;
      case 2:
      player.addTag("spectator_2")
      break;
      case 3:
      player.addTag("spectator_3")
      break;
      case 4:
      player.addTag("spectator_4")
      break;
      case 5:
      player.addTag("spectator_5")
      break;
      case 6:
      player.addTag("spectator_6")
      break;
      case 7:
      player.addTag("spectator_7")
      break;
      case 8:
      player.addTag("spectator_8")
      break;
      case 9:
      player.addTag("spectator_9")
      break;
      case 10:
      player.addTag("spectator_10")
      break;
      case 11:
      player.addTag("spectator_11")
      break;
      case 12:
      player.addTag("spectator_12")
      break;
    default:
      break;
  }
  player.runCommandAsync(`playsound random.orb @s`)
  player.sendMessage("signal");
  }).catch(error => {
    console.warn("Error", error);
  });
}
export function getNumeroDesdeTag(player) {
  const tags = player.getTags();
  const tag = tags.find(t => t.startsWith("spectator_"));
  if (!tag) return null;

  const match = tag.match(/\d+$/);
  return match ? parseInt(match[0]) : null;
}
export function getJugadorObservado(numero, world) {
  const objetivo = world.scoreboard.getObjective("players");
  if (!objetivo) return null;

  const jugadores = world.getPlayers();
  for (const p of jugadores) {
    const esSpectador = p.getTags().some(t => t.startsWith("spectator_"));
    if (esSpectador) continue;

    const score = objetivo.getScore(p);
    if (score == numero) {
      return p;
    }
  }

  return null;
}
export function mostrarEstadisticas(espectador, world) {
  const numero = getNumeroDesdeTag(espectador);
  if (numero == null) {
    espectador.sendMessage("§cError.");
    return;
  }

  const jugador = getJugadorObservado(numero, world);
  if (!jugador) {
    espectador.sendMessage(`§cError §e${numero}`);
    return;
  }

  const kills = world.scoreboard.getObjective("kills")?.getScore(jugador) ?? 0;
  const health = jugador.getComponent(EntityComponentTypes.Health)?.currentValue;

  let k = new ActionFormData()
    k.title(`§l${jugador.name}`)
    k.body(`
      Name: ${jugador.name}

      Kills: ${kills}

      Health: ${health}
      `)
    k.button("Ok");

  k.show(espectador).catch(() => {
    espectador.sendMessage("§cError.");
  });

}
export function MenuSettings(player){
    let j = new ModalFormData()
    j.dropdown("game.select_time",["game.options.time.sunrise","game.options.time.day","game.options.time.noon","game.options.time.sunset","game.options.time.night","game.options.time.midnight"])
    j.dropdown("game.select_weather",["game.options.weather.clear","game.options.wheater.rain","game.options.weather.thunder"])
    j.dropdown("game.select_difficulty",["options.difficulty.easy","options.difficulty.normal","options.difficulty.hard"])
  j.show(player).then(result => {
    if (result.canceled) {
        settings = false; 
      return;
    };
    switch (result.formValues[0]) {
      case 0:
        player.runCommandAsync("time set sunrise");
        break;
      case 1:
        player.runCommandAsync("time set day");
        break;
        case 2:
        player.runCommandAsync("time set noon");
        break;
        case 3:
        player.runCommandAsync("time set sunset");
        break;
      case 4:
        player.runCommandAsync("time set night");
        break;
        case 5:
        player.runCommandAsync("time set midnight");
        break;
      default:
        break;
    }
    switch (result.formValues[1]) {
      case 0:
        player.runCommandAsync("weather clear");
        break;
      case 1:
        player.runCommandAsync("weather rain");
        break;
        case 2:
        player.runCommandAsync("weather thunder");
        break;
      default:
        break;
    }
    switch (result.formValues[2]) {
      case 0:
        player.runCommandAsync("difficulty easy");
        break;
      case 1:
        player.runCommandAsync("difficulty normal");
        break;
        case 2:
        player.runCommandAsync("difficulty hard");
        break;
      default:
        break;
    }
    player.runCommandAsync('tellraw @s {"rawtext":[{"translate":"game.settings_saved"}]}');
    player.runCommandAsync(`playsound note.pling @s`);
    settings = false; 
  });
}
export function BattleRoyaleGame(player){
    let a = new ActionFormData()
    a.title("§l§k§ai§ei§bi§r §4§lBattle Royale §k§ai§ei§bi§r")
    a.body("game.text.what_to_do")
    a.button("game.button.royale_solo")
    a.button("game.button.show_rules")
    a.button("game.button.cancel");

  a.show(player).then(response => {
    if (response.canceled) {
        menu_br = false; 
      return;
    };
    switch (response.selection) {
      case 0:
        player.runCommandAsync("execute at @e[type=armor_stand,name=start,scores={games=0}] run function royale/startbattleroyale");
        player.runCommandAsync("execute at @e[type=armor_stand,name=start,scores={games=1}] run function royale/spectator");
        menu_br = false; 
        break;
      case 1:
        player.runCommandAsync("tellraw @s {\"rawtext\":[{\"translate\":\"game.royale_rules\"}]}");
        player.runCommandAsync("playsound random.orb @s");
        menu_br = false; 
        break;
      case 2:
        player.runCommandAsync("tellraw @s {\"rawtext\":[{\"translate\":\"game.royale_canceled\"}]}");
        menu_br = false; 
        break;
    }
  });
}
export function Menu(player) {
  let a = new ActionFormData()
  a.title("game.title.support_menu")
  a.body("§l§eTEF Battle Royale §k§ai§ci§bi§r")
  a.button("game.button.solve_problems")
  a.button("game.button.back_lobby")
  a.show(player).then(result => {
    if (result.selection == 0){
      SolveProblem(player);
    }
    if (result.selection == 1){
      ConfirmExit(player)
    }
  });
}
export function SolveProblem(player){
  let b = new ActionFormData()
  b.title("game.title.solve_problems")
  b.body("game.message.what_problem")
  b.button("game.button.player_nodeath")
  b.button("game.button.mode_nowork")
  b.button("game.button.reload_bug")
  b.button("game.button.back_menu")
  b.show(player).then(result => {
    if (result.selection == 0){
      player.runCommandAsync("function deathproblem");
    }
    if (result.selection == 1){
      ModeProblem(player);
    }
    if (result.selection == 3){
      Menu(player);
    }
    if (result.selection == 2){
      player.runCommandAsync('tellraw @a {"rawtext":[{"translate":"game.problem_fixed"}]}')
      player.runCommandAsync('playsound note.pling @a')
      player.runCommandAsync("execute at @a run event entity @a gabrielaplok:remove_reloading");
    }
  });
}
export function ModeProblem(player){
  let c = new ActionFormData()
  c.title("game.title.solve_problems")
  c.body("game.button.select_mode")
  c.button("§l§4Battle Royale")
  c.button("game.button.back_menu")
  c.show(player).then(result => {
    if (result.selection == 0){
      player.runCommandAsync("execute as @e[type=armor_stand,name=start,scores={games=1}] run function problem1")
      player.runCommandAsync("execute at @e[type=armor_stand,name=start,scores={games=!1}] run execute as @s run function notinmode")
    }
    if (result.selection == 1){
      Menu(player);
    }
  });
}
export function ConfirmExit(player){
  let d = new MessageFormData()
  d.title("game.title.exit")
  d.body("game.message.exit_confirmation")
  d.button2("game.button.yes")
  d.button1("game.button.no")
  d.show(player).then(result => {
    if (result.selection == 1){
      player.runCommandAsync("function resetallgames");
    }
  });
}
export function ConfirmExitTraining(player){
  let e = new MessageFormData()
  e.title("game.title.exit")
  e.body("game.message.exit_confirmation")
  e.button2("game.button.yes")
  e.button1("game.button.no")
  e.show(player).then(result => {
    if (result.selection == 1){
      player.runCommandAsync("function training/returntarget");
    }
  });
}
export function SettingsTraining(player){
  let f = new ModalFormData()
  f.dropdown("game.select_difficulty",["options.difficulty.easy","options.difficulty.normal","options.difficulty.hard"])
  f.show(player).then(result => {
    if(result.formValues[0] == 0){
      player.runCommandAsync("scoreboard players set @e[type=armor_stand,name=start] difficulty 1");
      player.runCommandAsync('tellraw @s {"rawtext":[{"translate":"game.bot.set_easy"}]}');
      player.runCommandAsync('event entity @e[type=converse:bot] easy');
      player.runCommandAsync(`playsound note.pling @s`);
    }
    if(result.formValues[0] == 1){
      player.runCommandAsync("scoreboard players set @e[type=armor_stand,name=start] difficulty 2");
      player.runCommandAsync('tellraw @s {"rawtext":[{"translate":"game.bot.set_normal"}]}');
      player.runCommandAsync('event entity @e[type=converse:bot] medium');
      player.runCommandAsync(`playsound note.pling @s`);
    }
    if(result.formValues[0] == 2){
      player.runCommandAsync("scoreboard players set @e[type=armor_stand,name=start] difficulty 3");
      player.runCommandAsync('tellraw @s {"rawtext":[{"translate":"game.bot.set_hard"}]}');
      player.runCommandAsync('event entity @e[type=converse:bot] hard');
      player.runCommandAsync(`playsound note.pling @s`);
    }
  });
}
export function menu_training(player) {
  let g = new ActionFormData()
  g.title("game.title.menu_training")
  g.button("game.button.start_target")
  g.button("game.button.go_fight")
  g.button("game.button.reset_inventory")
  g.button("game.settings_training")
  g.button("game.button.back_lobby")
  g.show(player).then(result => {
    if (result.selection == 0){
      player.runCommandAsync("function training/target_test");
    }
    if (result.selection == 1){
      player.runCommandAsync("function training/start");
    }
    if (result.selection == 2){
      player.runCommandAsync("clear @s");
      player.runCommandAsync('replaceitem entity @s slot.hotbar 8 converse:menu_training 1 0 {"item_lock":{"mode":"lock_in_slot"}}');
    }
    if (result.selection == 3){
      SettingsTraining(player)
    }
    if (result.selection == 4){
      ConfirmExitTraining(player)
    }
  });
}
export function Stats(player) {
  let h = new ActionFormData()
  h.title("game.title.menu_training")
  h.body(`
    Total Kills  : ${Score(player,"trainingkills")}

    Normal  : ${Score(player,"trainingkill")}

    Headshots  : ${Score(player,"trainingheadshot")}
    `)
  h.button("game.button.backto_target")
  h.button("game.settings_training")
  h.button("game.spawn_bots")
  h.button("game.button.back_lobby")
  h.show(player).then(result => {
    if (result.selection == 0){
      player.runCommandAsync("function training/back_target");
    }
    if (result.selection == 1){
      SettingsTraining(player)
    }
    if (result.selection == 2){
      player.runCommandAsync("function training/spawn_bots");
    }
    if (result.selection == 3){
      ConfirmExitTraining(player)
    }
  });
}
export function guide(player) {
  let a = new ActionFormData()
  a.title("game.title.guide")
  a.body("§l§eTheEpicFighters v1.1.5 §k§ai§ci§bi§r")
  a.button("game.button.modes","font/system")
  a.button("game.button.addfunctions")
  a.show(player).then(result => {
    if (result.selection == 0){
      Modes(player);
    }
    if (result.selection == 1){
      Addfunctions(player)
    }
  });
}
init();
