import {
  EntityInventoryComponent,
  ItemStack,
  Player,
  RawText,
  TicksPerSecond,
  TitleDisplayOptions,
  Vector3,
  World,
  system,
  world,
} from "@minecraft/server";
import { delayedRun } from "./utils/waitUtil";

class Pupeteer {
  private static getActualString(message: string): string | RawText {
    if (message.startsWith("%")) {
      const key = message.substring(1);
      return { rawtext: [{ translate: key }] };
    }
    return message;
  }

  static setActionBarTimed(message: string, duration: number): void {
    world.getPlayers().forEach((player) => {
      system.run(() => {
        player.onScreenDisplay.setActionBar(this.getActualString(message));
      });
    });
    delayedRun(() => {
      this.clearActionBar();
    }, duration * TicksPerSecond);
  }

  static setActionBar(message: string): void {
    world.getPlayers().forEach((player) => {
      system.run(() => {
        player.onScreenDisplay.setActionBar(this.getActualString(message));
      });
    });
  }

  static sendWorldMessage(message: string): void {
    world.sendMessage(this.getActualString(message));
  }

  static setTitleTimed(message: string, duration: number): void {
    world.getPlayers().forEach((player) => {
      let options: TitleDisplayOptions = {
        fadeInDuration: 20,
        fadeOutDuration: 20,
        stayDuration: duration * TicksPerSecond,
      };
      player.onScreenDisplay.setTitle(this.getActualString(message), options);
    });
  }

  static setTitle(message: string): void {
    world.getPlayers().forEach((player) => {
      player.onScreenDisplay.setTitle(message);
    });
  }

  static updateSubtitle(message: string): void {
    world.getPlayers().forEach((player) => {
      player.onScreenDisplay.updateSubtitle(this.getActualString(message));
    });
  }

  static clearTitle(): void {
    world.getPlayers().forEach((player) => {
      player.onScreenDisplay.setTitle("");
    });
  }

  static clearSubtitle(): void {
    world.getPlayers().forEach((player) => {
      player.onScreenDisplay.updateSubtitle("");
    });
  }

  static clearActionBar(): void {
    world.getPlayers().forEach((player) => {
      player.onScreenDisplay.setActionBar("");
    });
  }

  static testForLocation(location: Vector3, radius: number): boolean {
    let isPlayerInArea = false;
    world.getPlayers().forEach((player) => {
      let dx = location.x - player.location.x;
      let dy = location.y - player.location.y;
      let dz = location.z - player.location.z;

      let distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
      if (distance < radius) {
        isPlayerInArea = true;
      }
    });
    return isPlayerInArea;
  }

  static setNpcText(npcTag: string, sceneName: string) {
    world.getDimension("overworld").runCommand(`/dialogue change @e[tag=${npcTag}] ${sceneName} @a`);
  }

  static givePlayerItem(player: Player, item: ItemStack) {
    (player.getComponent("inventory") as EntityInventoryComponent).container!.addItem(item);
  }
}

export default Pupeteer;
