import { world, BlockPermutation, Player, system } from "@minecraft/server";

// ====================================================================
// --- ЧАСТЬ 1: КОНСТАНТЫ И УТИЛИТЫ ---
// ====================================================================

const POSE_MODIFIER_ITEM_ID = "mebesm:toy_pose_modifier";
// Устанавливаем кулдаун (0.34 секунды)
const COOLDOWN_MS = 340;
const PLAYER_COOLDOWNS = new Map();

/**
 * Утилита для создания циклической последовательности ID блоков: 
 * [baseId, baseId1, ..., baseIdN, baseId]
 */
const createCycle = (baseId, count) => {
  const ids = [baseId];
  for (let i = 1; i <= count; i++) {
    ids.push(`${baseId}${i}`);
  }
  ids.push(baseId); // Возвращение к начальному блоку для цикла
  return ids;
};

// Определяем все циклы блоков.
const BLOCK_CYCLES = {
  "mebesm:bron": createCycle("mebesm:bron", 6),
  "mebesm:boogie_bot": createCycle("mebesm:boogie_bot", 6),
  "mebesm:cat_bee": createCycle("mebesm:cat_bee", 6),
  "mebesm:huggy_wuggy_toy": createCycle("mebesm:huggy_wuggy_toy", 4),
  "mebesm:toy_huggy_box": createCycle("mebesm:toy_huggy_box", 6),
  "mebesm:boogie_bot_box": createCycle("mebesm:boogie_bot_box", 5),
  "mebesm:kissy_missy_toy": createCycle("mebesm:kissy_missy_toy", 4),
  "mebesm:candy_cat_box": createCycle("mebesm:candy_cat_box", 3),
  "mebesm:cube_yellow": createCycle("mebesm:cube_yellow", 3),
  "mebesm:cube_red": createCycle("mebesm:cube_red", 3),
  "mebesm:cube_blue": createCycle("mebesm:cube_blue", 3),
  "mebesm:cube_wooden": createCycle("mebesm:cube_wooden", 3),
  "mebesm:limon_toy": createCycle("mebesm:limon_toy", 3),
  "mebesm:barrel_red": createCycle("mebesm:barrel_red", 2),
  "mebesm:barrel_yellow": createCycle("mebesm:barrel_yellow", 2),
  "mebesm:barrel_blue": createCycle("mebesm:barrel_blue", 2),
};

// Все уникальные блоки, которые могут участвовать в цикле
const ALL_CYCLIC_BLOCKS = Object.values(BLOCK_CYCLES)
  .flat()
  .filter((id, index, self) => self.indexOf(id) === index);

// Обратная карта для быстрого поиска базового ID цикла
const BLOCK_TO_BASE_ID = new Map();
for (const baseId in BLOCK_CYCLES) {
  const cycle = BLOCK_CYCLES[baseId];
  // Записываем все ID блока в цикле, кроме последнего (который является повторением baseId)
  for (let i = 0; i < cycle.length - 1; i++) {
    BLOCK_TO_BASE_ID.set(cycle[i], baseId);
  }
}


/**
 * Определяет ID следующего блока в цикле, используя BLOCK_TO_BASE_ID для оптимизации.
 */
function get_next_block_id(currentBlockId) {
  const baseId = BLOCK_TO_BASE_ID.get(currentBlockId);

  if (!baseId) {
    return null;
  }

  const cycle = BLOCK_CYCLES[baseId];
  const currentIndex = cycle.indexOf(currentBlockId);

  // Возвращаем следующий элемент, если это не последний элемент в цикле (который является повторяющимся baseId)
  if (currentIndex !== -1 && currentIndex < cycle.length - 1) {
    return cycle[currentIndex + 1];
  }

  return null;
}

/**
 * Извлекает состояние направления блока ("minecraft:cardinal_direction") 
 * для сохранения его ориентации после смены позы.
 */
function getBlockDirectionState(block) {
  let blockStates = {};
  try {
    const direction = block.permutation.getState("minecraft:cardinal_direction");
    if (direction) {
      blockStates = { "minecraft:cardinal_direction": direction };
    }
  } catch { /* Если блок не имеет этого состояния, просто игнорируем */ }
  return blockStates;
}


// ====================================================================
// --- ЧАСТЬ 2: ЛОГИКА МОДИФИКАТОРА ПОЗ ---
// ====================================================================

/**
 * ЛОГИКА СМЕНЫ ПОЗЫ: Используется событие itemUseOn для взаимодействия.
 */
world.beforeEvents.itemUseOn.subscribe(event => {
  const { source, itemStack, block } = event;

  // 1. Предварительные проверки (Игрок, предмет)
  if (!(source instanceof Player) || !itemStack || itemStack.typeId !== POSE_MODIFIER_ITEM_ID) {
    return;
  }

  const currentBlockId = block.typeId;
  const player = source;

  // 2. Проверка: Является ли блок частью цикла
  if (!ALL_CYCLIC_BLOCKS.includes(currentBlockId)) {
    return;
  }

  // 3. Проверка на КУЛДАУН (защита от спама)
  const lastUseTime = PLAYER_COOLDOWNS.get(player.id) || 0;
  const currentTime = Date.now();

  if (currentTime - lastUseTime < COOLDOWN_MS) {
    event.cancel = true; // Отменить действие, если кулдаун не прошел
    return;
  }

  // 4. Определяем следующий ID блока
  const nextBlockId = get_next_block_id(currentBlockId);

  if (nextBlockId) {
    event.cancel = true; // Отменяем стандартное действие, чтобы блок не ломался/не ставился

    // Устанавливаем кулдаун
    PLAYER_COOLDOWNS.set(player.id, currentTime);

    // Запускаем асинхронное действие в следующем тике
    system.run(() => {
      // --- ДЕЙСТВИЕ 1: Смена блока (позы) ---
      const directionStates = getBlockDirectionState(block);
      const newPermutation = BlockPermutation.resolve(nextBlockId, directionStates);
      block.setPermutation(newPermutation);

      // --- ДЕЙСТВИЕ 2: Частицы ---
      const blockLocation = block.location;
      const particleLocation = {
        x: blockLocation.x + 0.5,
        y: blockLocation.y + 0.5,
        z: blockLocation.z + 0.5
      };
      // Вызываем кастомный эффект частиц
      block.dimension.spawnParticle("mebesm:toy_boom", particleLocation, newPermutation);

      // --- ДЕЙСТВИЕ 3: Звук ---
      // Проигрывается кастомный звук на позиции блока
      block.dimension.playSound("mob.besmc_nightmare_huggy.hurt", blockLocation, {
        pitch: 1.0,
        volume: 1.0
      });
    });
  }
});