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

// ====================================================================
// --- КОНСТАНТЫ ДЛЯ ВСЕХ ЧАСТЕЙ ---
// ====================================================================

// ЧАСТЬ 1: Ключ-карта
const REDSTONE_BLOCK_ID = "mebesm:access_card_slot_redstone";
const NORMAL_BLOCK_ID = "mebesm:access_card_slot";
const KEYCARD_ITEM_ID = "mebesm:vsc_keycard";

// ЧАСТЬ 2: Панель предохранителей
const FUSE_PANEL = "mebesm:fuse_panel";
const FUSE_RED = "mebesm:color_fuses_red";
const FUSE_BLUE = "mebesm:color_fuses_blue";
const FUSE_YELLOW = "mebesm:color_fuses_yellow";
const FUSE_GREEN = "mebesm:color_fuses_green";
const ALL_FUSES = [FUSE_RED, FUSE_BLUE, FUSE_YELLOW, FUSE_GREEN];

// ЧАСТЬ 4 & 5: Сканер и GrabPack
const CAT_BEE_ITEM_ID = "mebesm:cat_bee";
const GRABPACK_RED_ITEM_ID = "mebesm:grabpack_red";


/**
 * Получает состояние направления блока, если оно есть.
 * @param {Block} block Блок для проверки.
 * @returns {object} Объект состояний блока.
 */
function getBlockDirectionState(block) {
    let blockStates = {};
    try {
        const direction = block.permutation.getState("minecraft:cardinal_direction");
        if (direction) {
            blockStates = { "minecraft:cardinal_direction": direction };
        }
    } catch { }
    return blockStates;
}


// ====================================================================
// --- ЧАСТЬ 1: ЛОГИКА СЛОТОВ КЛЮЧ-КАРТЫ ---
// ====================================================================

// ЛОГИКА 1.1: АКТИВАЦИЯ КАРТЫ (ВСТАВИТЬ)
world.beforeEvents.itemUseOn.subscribe(event => {
    const { source, itemStack, block } = event;
    if (!(source instanceof Player) || !itemStack || block.typeId !== NORMAL_BLOCK_ID || itemStack.typeId !== KEYCARD_ITEM_ID) {
        return;
    }
    event.cancel = true;
    system.run(() => {
        const player = source;
        const directionStates = getBlockDirectionState(block);
        const newPermutation = BlockPermutation.resolve(REDSTONE_BLOCK_ID, directionStates);
        block.setPermutation(newPermutation);
        player.runCommandAsync(`clear @s ${KEYCARD_ITEM_ID} 0 1`);
    });
});


// ЛОГИКА 1.2: ДЕАКТИВАЦИЯ КАРТЫ (ЗАБРАТЬ)
world.beforeEvents.playerInteractWithBlock.subscribe(event => {
    const { player, block, itemStack } = event;
    if (block.typeId !== REDSTONE_BLOCK_ID || (itemStack && itemStack.typeId === KEYCARD_ITEM_ID)) {
        return;
    }
    // Дополнительная проверка, чтобы не конфликтовать с Логикой 2 и 3/4/5
    if (block.typeId.startsWith("mebesm:fuse_panel") || block.typeId.startsWith("mebesm:wall_lamp") || block.typeId.startsWith("mebesm:toy_scanner") || block.typeId.startsWith("mebesm:red_hand")) {
        return;
    }

    event.cancel = true;
    system.run(() => {
        const directionStates = getBlockDirectionState(block);
        const newPermutation = BlockPermutation.resolve(NORMAL_BLOCK_ID, directionStates);
        block.setPermutation(newPermutation);
        player.runCommandAsync(`give @s ${KEYCARD_ITEM_ID} 1`);
    });
});


// ====================================================================
// --- ЧАСТЬ 2: ЛОГИКА ПАНЕЛИ ПРЕДОХРАНИТЕЛЕЙ (ПОСЛЕДОВАТЕЛЬНАЯ) ---
// ====================================================================

const PANEL_TRANSITIONS_FORWARD = [
    [FUSE_PANEL, FUSE_RED, "mebesm:fuse_panel1"],
    ["mebesm:fuse_panel1", FUSE_BLUE, "mebesm:fuse_panel2"],
    ["mebesm:fuse_panel2", FUSE_YELLOW, "mebesm:fuse_panel3"],
    ["mebesm:fuse_panel3", FUSE_GREEN, "mebesm:fuse_panel4"]
];

const PANEL_TRANSITIONS_BACKWARD = [
    ["mebesm:fuse_panel4", FUSE_GREEN, "mebesm:fuse_panel3"],
    ["mebesm:fuse_panel3", FUSE_YELLOW, "mebesm:fuse_panel2"],
    ["mebesm:fuse_panel2", FUSE_BLUE, "mebesm:fuse_panel1"],
    ["mebesm:fuse_panel1", FUSE_RED, FUSE_PANEL]
];


// ЛОГИКА 2.1: АКТИВАЦИЯ/СМЕНА (ВСТАВИТЬ ПРЕДОХРАНИТЕЛЬ)
world.beforeEvents.itemUseOn.subscribe(event => {
    const { source, itemStack, block } = event;

    if (!(source instanceof Player) || !itemStack) {
        return;
    }

    const currentBlockId = block.typeId;
    const itemTypeId = itemStack.typeId;

    const transition = PANEL_TRANSITIONS_FORWARD.find(([current, fuse]) =>
        current === currentBlockId && fuse === itemTypeId
    );

    if (transition) {
        const [, , nextBlockId] = transition;
        event.cancel = true;

        system.run(() => {
            const player = source;
            const directionStates = getBlockDirectionState(block);
            const newPermutation = BlockPermutation.resolve(nextBlockId, directionStates);
            block.setPermutation(newPermutation);
            player.runCommandAsync(`clear @s ${itemTypeId} 0 1`);
        });
    }
});


// ЛОГИКА 2.2: ДЕАКТИВАЦИЯ/ОТКАТ (ЗАБРАТЬ ПРЕДОХРАНИТЕЛЬ)
world.beforeEvents.playerInteractWithBlock.subscribe(event => {
    const { player, block, itemStack } = event;

    if (itemStack && ALL_FUSES.includes(itemStack.typeId)) {
        return; // Приоритет ВСТАВИТЬ
    }

    const currentBlockId = block.typeId;

    const transition = PANEL_TRANSITIONS_BACKWARD.find(([current]) =>
        current === currentBlockId
    );

    if (transition) {
        const [, returnedItemId, prevBlockId] = transition;
        event.cancel = true;

        system.run(() => {
            const directionStates = getBlockDirectionState(block);
            const newPermutation = BlockPermutation.resolve(prevBlockId, directionStates);
            block.setPermutation(newPermutation);
            player.runCommandAsync(`give @s ${returnedItemId} 1`);
        });
    }
});


// ====================================================================
// --- ЧАСТЬ 3: ЛОГИКА НАСТЕННОЙ ЛАМПЫ (КЛИК = ВКЛ/ВЫКЛ) ---
// ====================================================================

// Структура для хранения всех пар ламп (OFF -> ON)
// !!! ИСПРАВЛЕНО: mebesm:lamp_on_the_wall_off -> mebesm:lamp_on_the_wall !!!
const LAMP_TRANSITIONS = {
    // Старая лампа
    "mebesm:wall_lamp_off": "mebesm:wall_lamp_on",

    // Новые лампы
    "mebesm:large_ceiling_lamp_off": "mebesm:large_ceiling_lamp",
    "mebesm:signal_lamp_off": "mebesm:signal_lamp",
    "mebesm:wall_ceiling_lamp_off": "mebesm:wall_ceiling_lamp",
    "mebesm:lamp_on_the_wall_off": "mebesm:lamp_on_the_wall" // ИСПРАВЛЕНО
};

// Создаем обратный список для перехода (ON -> OFF)
const LAMP_TRANSITIONS_REVERSE = {};
for (const [offId, onId] of Object.entries(LAMP_TRANSITIONS)) {
    LAMP_TRANSITIONS_REVERSE[onId] = offId;
}

// Объединяем все возможные ID ламп для быстрой проверки
const ALL_LAMP_IDS = new Set([
    ...Object.keys(LAMP_TRANSITIONS),
    ...Object.keys(LAMP_TRANSITIONS_REVERSE)
]);


/**
 * ЛОГИКА 3.1: Переключение лампы
 * Срабатывает при клике по блоку (пустой рукой или не-спец-предметом).
 */
world.beforeEvents.playerInteractWithBlock.subscribe(event => {
    const { player, block, itemStack } = event;

    if (!(player instanceof Player)) {
        return;
    }

    const currentBlockId = block.typeId;

    // 1. Проверяем, является ли блок одной из ламп
    if (!ALL_LAMP_IDS.has(currentBlockId)) {
        return;
    }

    // 2. Проверяем, не сработала ли уже Логика 1, 2, 4 или 5 (конфликты с интерактивными предметами)
    if (itemStack && (itemStack.typeId === KEYCARD_ITEM_ID ||
        ALL_FUSES.includes(itemStack.typeId) ||
        itemStack.typeId === CAT_BEE_ITEM_ID ||
        itemStack.typeId === GRABPACK_RED_ITEM_ID)) {
        return;
    }

    let targetBlockId = null;

    // 3. Определяем, на что менять:
    if (LAMP_TRANSITIONS[currentBlockId]) {
        // OFF -> ON
        targetBlockId = LAMP_TRANSITIONS[currentBlockId];
    } else if (LAMP_TRANSITIONS_REVERSE[currentBlockId]) {
        // ON -> OFF
        targetBlockId = LAMP_TRANSITIONS_REVERSE[currentBlockId];
    } else {
        return;
    }


    event.cancel = true; // Отменяем стандартное действие

    system.run(() => {
        const directionStates = getBlockDirectionState(block);
        const newPermutation = BlockPermutation.resolve(targetBlockId, directionStates);

        // Замена блока
        block.setPermutation(newPermutation);
    });
});


// ====================================================================
// --- ЧАСТЬ 4: ЛОГИКА СКАНЕРА ИГРУШЕК ---
// ====================================================================

const SCANNER_OFF_ID = "mebesm:toy_scanner";
const SCANNER_ON_ID = "mebesm:toy_scanner_on";

// ЛОГИКА 4.1: АКТИВАЦИЯ СКАНЕРА (ВСТАВИТЬ ИГРУШКУ)
world.beforeEvents.itemUseOn.subscribe(event => {
    const { source, itemStack, block } = event;

    // Проверка на игрока, наличие предмета, правильный блок (выключенный сканер) и правильный предмет (CatBee)
    if (!(source instanceof Player) || !itemStack || block.typeId !== SCANNER_OFF_ID || itemStack.typeId !== CAT_BEE_ITEM_ID) {
        return;
    }

    event.cancel = true;

    system.run(() => {
        const player = source;
        const directionStates = getBlockDirectionState(block);

        // Меняем на блок "ВКЛЮЧЕННЫЙ СКАНИРОВАНИЕ"
        const newPermutation = BlockPermutation.resolve(SCANNER_ON_ID, directionStates);
        block.setPermutation(newPermutation);

        // Удаляем один предмет CatBee у игрока
        player.runCommandAsync(`clear @s ${CAT_BEE_ITEM_ID} 0 1`);
    });
});


// ЛОГИКА 4.2: ДЕАКТИВАЦИЯ СКАНЕРА (ЗАБРАТЬ ИГРУШКУ)
world.beforeEvents.playerInteractWithBlock.subscribe(event => {
    const { player, block, itemStack } = event;

    // 1. Проверяем, что это включенный сканер
    if (block.typeId !== SCANNER_ON_ID) {
        return;
    }

    // 2. Проверяем, что в руке НЕ CatBee (чтобы не конфликтовать с Логикой 4.1)
    if (itemStack && itemStack.typeId === CAT_BEE_ITEM_ID) {
        return;
    }

    // 3. Проверяем, что в руке НЕ ключ-карта/предохранитель (чтобы не конфликтовать с Логикой 1.2/2.2)
    if (itemStack && (itemStack.typeId === KEYCARD_ITEM_ID || ALL_FUSES.includes(itemStack.typeId))) {
        return;
    }


    event.cancel = true;

    system.run(() => {
        const directionStates = getBlockDirectionState(block);

        // Меняем на блок "ВЫКЛЮЧЕННЫЙ СКАНИРОВАНИЕ"
        const newPermutation = BlockPermutation.resolve(SCANNER_OFF_ID, directionStates);
        block.setPermutation(newPermutation);

        // Отдаем один предмет CatBee игроку
        player.runCommandAsync(`give @s ${CAT_BEE_ITEM_ID} 1`);
    });
});


// ====================================================================
// --- ЧАСТЬ 5: ЛОГИКА ЭКСПОНАТА КРАСНОЙ РУКИ (GRABPACK) ---
// ====================================================================

const RED_HAND_ON_ID = "mebesm:red_hand_exhibit";
const RED_HAND_OFF_ID = "mebesm:red_hand_exhibit_off";

/**
 * ЛОГИКА 5.1: ДЕАКТИВАЦИЯ (ВСТАВИТЬ GRABPACK)
 * Срабатывает при использовании mebesm:grabpack_red на блоке red_hand_exhibit_off.
 */
world.beforeEvents.itemUseOn.subscribe(event => {
    const { source, itemStack, block } = event;

    // Проверка 1: Игрок, наличие предмета, блок OFF, предмет GRABPACK
    if (!(source instanceof Player) || !itemStack || block.typeId !== RED_HAND_OFF_ID || itemStack.typeId !== GRABPACK_RED_ITEM_ID) {
        return;
    }

    event.cancel = true;

    system.run(() => {
        const player = source;
        const directionStates = getBlockDirectionState(block);

        // Меняем на блок "ВКЛЮЧЕННЫЙ/ОБЫЧНЫЙ"
        const newPermutation = BlockPermutation.resolve(RED_HAND_ON_ID, directionStates);
        block.setPermutation(newPermutation);

        // Удаляем два предмета GrabPack у игрока
        player.runCommandAsync(`clear @s ${GRABPACK_RED_ITEM_ID} 0 2`);
    });
});


/**
 * ЛОГИКА 5.2: АКТИВАЦИЯ (ЗАБРАТЬ GRABPACK)
 * Срабатывает при клике ПУСТОЙ РУКОЙ по блоку red_hand_exhibit.
 */
world.beforeEvents.playerInteractWithBlock.subscribe(event => {
    const { player, block, itemStack } = event;

    // Проверка 1: правильный блок (включенный/обычный)
    if (block.typeId !== RED_HAND_ON_ID) {
        return;
    }

    // Проверка 2: пустая рука (itemStack должен быть null/undefined)
    if (itemStack) {
        return;
    }

    // Дополнительная проверка на другие блоки, хотя typeId уже отфильтрован.
    if (block.typeId.startsWith("mebesm:access_card_slot") ||
        block.typeId.startsWith("mebesm:fuse_panel") ||
        block.typeId.startsWith("mebesm:wall_lamp") ||
        block.typeId.startsWith("mebesm:toy_scanner")) {
        return;
    }

    event.cancel = true;

    system.run(() => {
        const directionStates = getBlockDirectionState(block);

        // Меняем на блок "ВЫКЛЮЧЕННЫЙ"
        const newPermutation = BlockPermutation.resolve(RED_HAND_OFF_ID, directionStates);
        block.setPermutation(newPermutation);

        // Выдаем два предмета GrabPack игроку
        player.runCommandAsync(`give @s ${GRABPACK_RED_ITEM_ID} 2`);
    });
});