// kubejs/server_scripts/vs_bridge_test.js
// Commands:
//   /vsjs_test        -> one-shot report
//   /vsjs_watch on    -> start watching (prints once per second)
//   /vsjs_watch off   -> stop watching

const WATCH_KEY = "vsjs_watch_enabled"

// --- small helpers ---
function fmt3(a) {
  if (!a) return "null"
  return `${a[0].toFixed(3)}, ${a[1].toFixed(3)}, ${a[2].toFixed(3)}`
}
function fmt4(a) {
  if (!a) return "null"
  return `${a[0].toFixed(4)}, ${a[1].toFixed(4)}, ${a[2].toFixed(4)}, ${a[3].toFixed(4)}`
}
function ok(b) { return b ? "§aOK§r" : "§cFAIL§r" }

function report(player, header, lines) {
  player.tell(`§6[vsjs] ${header}§r`)
  for (const l of lines) player.tell(`  ${l}`)
}

function oneShot(player) {
  const js = VS.js()
  const level = player.serverLevel()

  // --- STRICT: ship under player ---
  const strictShip = js.getShipPlayerIsOnStrict(player)
  const onStrict = js.isPlayerOnShipStrict(player)

  // --- CLAIM: ship claim at player's block pos ---
  const claimedShip = js.getClaimedShipAtPlayer(player)
  const inClaim = js.isPlayerInClaimedShipArea(player)

  // --- BROAD: ships at player point ---
  const broadShips = js.getShipsAtBroad(level, player.getX(), player.getY(), player.getZ())
  const broadCount = broadShips ? broadShips.size() : 0

  // --- MOUNT ---
  const isMounted = js.isShipMountingEntity(player)
  const mountedShip = js.getMountedShip(player)

  // --- KINEMATICS (only if we have a ship) ---
  const ship = strictShip || claimedShip || (broadShips && broadShips.size() > 0 ? broadShips.get(0) : null)

  let vel = null, ang = null, pos = null, rot = null, spd = 0, hsp = 0
  let shipId = "null"
  if (ship) {
    // Ship is a Java object; depending on KubeJS binding, either ship.id or ship.getId() may work.
    try { shipId = ship.getId ? String(ship.getId()) : String(ship.id) } catch (e) { shipId = "unknown" }

    vel = js.getShipVelocity(ship)
    ang = js.getShipAngularVelocity(ship)
    pos = js.getShipPosition(ship)
    rot = js.getShipRotation(ship)
    spd = js.getShipSpeed(ship)
    hsp = js.getShipHorizontalSpeed(ship)
  }

  // --- Output ---
  report(player, "Bridge one-shot test", [
    `Strict on-ship: ${ok(onStrict)}  (ship=${strictShip ? "yes" : "no"})`,
    `Claim in-ship-area: ${ok(inClaim)}  (ship=${claimedShip ? "yes" : "no"})`,
    `Broad ships at player point: ${broadCount}`,
    `Mount(VS): ${isMounted ? "true" : "false"}  (mountedShip=${mountedShip ? "yes" : "no"})`,
    `Selected ship.id: ${shipId}`,
    `pos: ${fmt3(pos)}`,
    `vel: ${fmt3(vel)}  speed=${spd.toFixed(3)}  horiz=${hsp.toFixed(3)}`,
    `ang: ${fmt3(ang)}`,
    `rot(q): ${fmt4(rot)}`
  ])
}

// ------------------------------------------------------------
// Command registration
// ------------------------------------------------------------
ServerEvents.commandRegistry(event => {
  const { commands: Commands } = event

  // /vsjs_test
  event.register(
    Commands.literal("vsjs_test").executes(ctx => {
      const player = ctx.source.playerOrException
      oneShot(player)
      return 1
    })
  )

  // /vsjs_watch on|off
  event.register(
    Commands.literal("vsjs_watch")
      .then(
        Commands.literal("on").executes(ctx => {
          const player = ctx.source.playerOrException
          player.persistentData.putBoolean(WATCH_KEY, true)
          player.tell("§a[vsjs] watch enabled (prints once per second).§r")
          return 1
        })
      )
      .then(
        Commands.literal("off").executes(ctx => {
          const player = ctx.source.playerOrException
          player.persistentData.putBoolean(WATCH_KEY, false)
          player.tell("§e[vsjs] watch disabled.§r")
          return 1
        })
      )
  )
})

// ------------------------------------------------------------
// Watch loop: once per second per player
// ------------------------------------------------------------
ServerEvents.tick(event => {
  // 20 ticks = 1 second
  if (event.server.tickCount % 20 !== 0) return

  for (const player of event.server.players) {
    if (!player.persistentData.getBoolean(WATCH_KEY)) continue

    const js = VS.js()
    const ship = js.getShipPlayerIsOnStrict(player)

    if (!ship) {
      player.tell("§c[vsjs] watch: no strict ship under you.§r")
      continue
    }

    const vel = js.getShipVelocity(ship)
    const pos = js.getShipPosition(ship)
    const spd = js.getShipSpeed(ship)

    player.tell(`§a[vsjs] watch pos(${fmt3(pos)}) vel(${fmt3(vel)}) speed=${spd.toFixed(2)}§r`)
  }
})
