// Herramientas administrativas pequenas para revisar claims sin tocar datos de OPAC.
function cuniclaimsSourceCanUse(source) {
  try {
    return source && source.hasPermission(2);
  } catch (ignored) {
    return false;
  }
}

function cuniclaimsTell(server, playerName, message, color) {
  if (!server || !playerName) {
    return;
  }
  var safe = String(message || '').replace(/\\/g, '\\\\').replace(/"/g, '\\"');
  server.runCommandSilent('tellraw ' + playerName + ' {"text":"' + safe + '","color":"' + (color || 'gold') + '"}');
}

function cuniclaimsSafePlayerName(player) {
  try {
    var name = String(player.username || '');
    return /^[A-Za-z0-9_]{1,16}$/.test(name) ? name : '';
  } catch (ignored) {
    return '';
  }
}

function cuniclaimsDimension(raw) {
  var value = String(raw || 'minecraft:overworld').toLowerCase();
  if (value === 'overworld' || value === 'mundo' || value === 'normal') {
    return 'minecraft:overworld';
  }
  if (value === 'nether') {
    return 'minecraft:the_nether';
  }
  if (value === 'end') {
    return 'minecraft:the_end';
  }
  if (value === 'spawn' || value === 'lobby') {
    return 'minecraft:overworld';
  }
  if (/^[a-z0-9_.-]+:[a-z0-9_./-]+$/.test(value)) {
    return value;
  }
  return 'minecraft:overworld';
}

function cuniclaimsParseInteger(raw) {
  var value = Number(String(raw || '').trim());
  if (!isFinite(value)) {
    return null;
  }
  return Math.floor(value);
}

function cuniclaimsTeleport(source, blockX, blockZ, dimension) {
  var server = source.getServer();
  var player = source.getPlayer();
  var playerName = cuniclaimsSafePlayerName(player);
  if (!server || !player || !playerName) {
    return 0;
  }

  var dim = cuniclaimsDimension(dimension);
  var x = Math.floor(Number(blockX || 0));
  var z = Math.floor(Number(blockZ || 0));
  var y = 180;
  server.runCommandSilent('execute in ' + dim + ' run tp ' + playerName + ' ' + x + ' ' + y + ' ' + z);
  cuniclaimsTell(server, playerName, '[CUNICULUM] Teletransporte de revision: ' + dim + ' X ' + x + ' Z ' + z + '. Baja con fly/spectator si hace falta.', 'aqua');
  return 1;
}

function cuniclaimsTeleportChunk(ctx, chunkXRaw, chunkZRaw, dimensionRaw) {
  var source = ctx.getSource();
  var server = source.getServer();
  var player = source.getPlayer();
  var playerName = cuniclaimsSafePlayerName(player);
  var chunkX = cuniclaimsParseInteger(chunkXRaw);
  var chunkZ = cuniclaimsParseInteger(chunkZRaw);
  if (chunkX === null || chunkZ === null) {
    cuniclaimsTell(server, playerName, '[CUNICULUM] Uso: /claimtp <chunk_x> <chunk_z> [dimension]', 'red');
    return 0;
  }
  return cuniclaimsTeleport(source, chunkX * 16 + 8, chunkZ * 16 + 8, dimensionRaw || 'minecraft:overworld');
}

function cuniclaimsTeleportBlock(ctx, xRaw, zRaw, dimensionRaw) {
  var source = ctx.getSource();
  var server = source.getServer();
  var player = source.getPlayer();
  var playerName = cuniclaimsSafePlayerName(player);
  var x = cuniclaimsParseInteger(xRaw);
  var z = cuniclaimsParseInteger(zRaw);
  if (x === null || z === null) {
    cuniclaimsTell(server, playerName, '[CUNICULUM] Uso: /claimtp block <x> <z> [dimension]', 'red');
    return 0;
  }
  return cuniclaimsTeleport(source, x, z, dimensionRaw || 'minecraft:overworld');
}

function cuniclaimsHelp(ctx) {
  var source = ctx.getSource();
  var server = source.getServer();
  var playerName = cuniclaimsSafePlayerName(source.getPlayer());
  cuniclaimsTell(server, playerName, '[CUNICULUM] /claimtp <chunk_x> <chunk_z> [overworld|nether|dimension] te lleva al centro del chunk.', 'gold');
  cuniclaimsTell(server, playerName, '[CUNICULUM] /claimtp block <x> <z> [dimension] te lleva a coordenadas de bloque.', 'yellow');
  cuniclaimsTell(server, playerName, '[CUNICULUM] Para revisar/interactuar claims ajenos usa tambien el modo admin de Open Parties and Claims.', 'aqua');
  return 1;
}

ServerEvents.commandRegistry(function (event) {
  var commands = event.commands;
  var args = event.arguments;
  var word = function (name) { return commands.argument(name, args.STRING.create(event)); };

  event.register(
    commands.literal('claimtp')
      .requires(function (source) { return cuniclaimsSourceCanUse(source); })
      .executes(function (ctx) { return cuniclaimsHelp(ctx); })
      .then(commands.literal('help')
        .executes(function (ctx) { return cuniclaimsHelp(ctx); }))
      .then(commands.literal('block')
        .then(word('x')
          .then(word('z')
            .executes(function (ctx) {
              return cuniclaimsTeleportBlock(ctx, args.STRING.getResult(ctx, 'x'), args.STRING.getResult(ctx, 'z'), 'minecraft:overworld');
            })
            .then(word('dimension')
              .executes(function (ctx) {
                return cuniclaimsTeleportBlock(ctx, args.STRING.getResult(ctx, 'x'), args.STRING.getResult(ctx, 'z'), args.STRING.getResult(ctx, 'dimension'));
              })))))
      .then(word('chunk_x')
        .then(word('chunk_z')
          .executes(function (ctx) {
            return cuniclaimsTeleportChunk(ctx, args.STRING.getResult(ctx, 'chunk_x'), args.STRING.getResult(ctx, 'chunk_z'), 'minecraft:overworld');
          })
          .then(word('dimension')
            .executes(function (ctx) {
              return cuniclaimsTeleportChunk(ctx, args.STRING.getResult(ctx, 'chunk_x'), args.STRING.getResult(ctx, 'chunk_z'), args.STRING.getResult(ctx, 'dimension'));
            }))))
  );
});
