import { world, ItemStack, system } from "@minecraft/server";
import { getTemperatureTag } from "./temperature_id.js";

// Новый: тип сущности кега
const crafting_entity_type = "brewinandchewin:keg";

// Импорт общих утилит и списка рецептов
import recipes from "./recipes/recipes_index.js";
import {
    liquidSlot, resultSlot, slotGen, cookTimeTotal, cookTimeTotalMini,
    isResultSlotFull, consumeItem, addResult, returnTaraToBuffer,
    allowedMeats, allowedVeggies, kippersFishIds
} from "./recipes/helpers.js";

// === Общие функции для прогресс-бара и пузырьков ===
function updateCookingProgressBar(inv, cookTime, cookTimeTotal) {
    const cookingProgressValue = Math.min(22, Math.ceil((cookTime / cookTimeTotal) * 22));
    const cookingProgressItem = new ItemStack("minecraft:stick", 1);
    cookingProgressItem.nameTag = `${cookingProgressValue}`;
    inv.setItem(7, cookingProgressItem);
}

const bubbleStates = new Map();
function updateBubbleBars(inv, kegId, active, forceReset = false) {
    let state = bubbleStates.get(kegId) || { tick: 0 };
    const leftMax = 17;
    const rightMax = 19;
    const cycleTicks = 180;
    const leftStep = cycleTicks / (leftMax + 1);
    const rightStep = cycleTicks / (rightMax + 1);
    if (forceReset) {
        state.tick = 0;
    } else if (active) {
        state.tick = (typeof state.tick === 'number' ? state.tick : 0) + 2.25;
        if (state.tick >= cycleTicks) state.tick = 0;
    }
    const leftValue = Math.floor(state.tick / leftStep);
    const rightValue = Math.floor(state.tick / rightStep);
    const leftItem = new ItemStack("minecraft:stick", 1);
    leftItem.nameTag = `${leftValue}`;
    inv.setItem(8, leftItem);
    const rightItem = new ItemStack("minecraft:stick", 1);
    rightItem.nameTag = `${rightValue}`;
    inv.setItem(9, rightItem);
    bubbleStates.set(kegId, state);
}

const lastTempTags = new Map();
const revertStates = new Map();

// === Список id тары ===
const containerIds = [
    "minecraft:glass_bottle",
    "minecraft:bucket",
    "brewinandchewin:tankard",
];

function isTara(item) {
    return containerIds.includes(item.typeId);
}

// === ВСПОМОГАТЕЛЬНАЯ ФУНКЦИЯ ДЛЯ ВОЗВРАТА ТАРЫ ===
function returnTaraToBuffer(inv, typeId, amount) {
    for (let i = 11; i <= 26 && amount > 0; i++) {
        let slotItem = inv.getItem(i);
        if (slotItem && slotItem.typeId === typeId && slotItem.amount < slotItem.maxAmount) {
            let canAdd = Math.min(amount, slotItem.maxAmount - slotItem.amount);
            slotItem.amount += canAdd;
            amount -= canAdd;
            inv.setItem(i, slotItem);
        }
    }
    for (let i = 11; i <= 26 && amount > 0; i++) {
        if (!inv.getItem(i)) {
            let toPlace = Math.min(amount, 64);
            inv.setItem(i, new ItemStack(typeId, toPlace));
            amount -= toPlace;
        }
    }
}

// === Функция проверки заполненности 5-го слота ===
function isResultSlotFull(inv) {
    const resultItem = inv.getItem(resultSlot);
    if (!resultItem) return false;
    const maxStackSize = resultItem.maxAmount || 64;
    return resultItem.amount >= maxStackSize;
}

// === Общие функции для обработки рецептов ===
function consumeItem(inv, slot, amount = 1) {
    const item = inv.getItem(slot);
    if (!item) return;
    if (item.amount > amount) {
        item.amount -= amount;
        inv.setItem(slot, item);
    } else {
        inv.setItem(slot, undefined);
    }
}

function addResult(inv, resultId, amount) {
    const result = inv.getItem(resultSlot);
    if (!result) {
        inv.setItem(resultSlot, new ItemStack(resultId, amount));
    } else {
        result.amount += amount;
        inv.setItem(resultSlot, result);
    }
}

function spawnXPOrb(overworld, location) {
    const players = overworld.getPlayers({
        location: location,
        maxDistance: 5
    });
    if (players.length > 0) {
        overworld.spawnEntity("minecraft:xp_orb", {
            x: location.x + 0.5,
            y: location.y + 1,
            z: location.z + 0.5,
            amount: 1
        });
    }
}

function resetCookingProgress(inv, keg, overworld) {
    keg.setDynamicProperty("cook_time", 0);
    const progressItem = new ItemStack("minecraft:stick", 1);
    progressItem.nameTag = "0";
    inv.setItem(7, progressItem);
    updateBubbleBars(inv, keg.id, false, true);
    spawnXPOrb(overworld, keg.location);
}

function processRecipe(inv, keg, overworld, recipe, cookTime, tempSlot) {
    if (!recipe.isValid(inv, tempSlot) || isResultSlotFull(inv)) return false;
    
    revertStates.delete(keg.id);
    cookTime++;
    keg.setDynamicProperty("cook_time", cookTime);
    updateCookingProgressBar(inv, cookTime, recipe.cookTime);
    
    const progressItem = inv.getItem(7);
    let progressActive = false;
    if (progressItem && progressItem.nameTag) {
        const val = parseInt(progressItem.nameTag);
        progressActive = val >= 1 && val <= 22;
    }
    updateBubbleBars(inv, keg.id, progressActive);
    
    if (cookTime >= recipe.cookTime) {
        recipe.onComplete(inv, keg, overworld);
        resetCookingProgress(inv, keg, overworld);
    }
    return true;
}

// === Основной цикл обработки ===
system.runInterval(() => {
    const overworld = world.getDimension("overworld");
    const kegs = overworld.getEntities({ type: crafting_entity_type });
    
    for (const keg of kegs) {
        const inv = keg.getComponent("inventory").container;
        let cookTime = keg.getDynamicProperty("cook_time") || 0;
        
        // Обновление температурного слота
        const tempTag = getTemperatureTag(keg);
        if (typeof tempTag === "number") {
            lastTempTags.set(keg.id, tempTag);
            const tempItem = new ItemStack("minecraft:stick", 1);
            tempItem.nameTag = `${tempTag}`;
            inv.setItem(10, tempItem);
        } else if (lastTempTags.has(keg.id)) {
            const prevTag = lastTempTags.get(keg.id);
            const tempItem = new ItemStack("minecraft:stick", 1);
            tempItem.nameTag = `${prevTag}`;
            inv.setItem(10, tempItem);
        }
        const tempSlot = inv.getItem(10);
        
        // Попытка обработать рецепты
        let recipeProcessed = false;
        for (const recipe of recipes) {
            if (processRecipe(inv, keg, overworld, recipe, cookTime, tempSlot)) {
                recipeProcessed = true;
                cookTime = keg.getDynamicProperty("cook_time") || 0;
                break;
            }
        }
        
        // Если ни один рецепт не подходит — плавный откат баров
        if (!recipeProcessed) {
            let currentProgress = inv.getItem(7)?.nameTag ? parseFloat(inv.getItem(7).nameTag) : 0;
            let currentBubble = bubbleStates.get(keg.id)?.tick ?? 0;
            
            // Если cookTime > 0, проверяем, может ли какой-то рецепт быть валидным
            // Это предотвращает откат при временных сбоях (например, при клике игрока)
            let shouldWaitForRecipe = false;
            if (cookTime > 0) {
                // Проверяем, может ли хоть один рецепт быть валидным
                for (const recipe of recipes) {
                    if (recipe.isValid(inv, tempSlot) && !isResultSlotFull(inv)) {
                        shouldWaitForRecipe = true;
                        break;
                    }
                }
            }
            
            // Восстановление прогресс-бара из cook_time при мерцании
            // Если рецепт потенциально валиден, не начинаем откат
            if (shouldWaitForRecipe) {
                // Просто поддерживаем текущий прогресс из cookTime, не начинаем откат
                updateCookingProgressBar(inv, cookTime, cookTimeTotal);
                const progressItem = inv.getItem(7);
                let progressActive = false;
                if (progressItem && progressItem.nameTag) {
                    const val = parseInt(progressItem.nameTag);
                    progressActive = val >= 1 && val <= 22;
                }
                updateBubbleBars(inv, keg.id, progressActive);
                revertStates.delete(keg.id);
                continue;
            }
            
            // Дополнительная проверка для рецептов с жидкостью
            let triggerRevert = false;
            if ((currentProgress > 0 || currentBubble > 0)) {
                const slot4Item = inv.getItem(4);
                if (slot4Item && slot4Item.typeId === "farmersdelight:milk_bottle" && slot4Item.amount < 2) {
                    triggerRevert = true;
                }
                if (slot4Item && slot4Item.typeId === "minecraft:honey_bottle" && slot4Item.amount < 1) {
                    triggerRevert = true;
                }
            }
            
            let revert = revertStates.get(keg.id) || { progress: null, tick: null, revertTicks: 0 };
            if ((currentProgress > 0 || currentBubble > 0) || triggerRevert) {
                if (revert.revertTicks === 0) {
                    revert.progress = currentProgress;
                    revert.tick = currentBubble;
                }
                revert.revertTicks++;
                let progressStep = (revert.progress || 0) / 1200;
                let bubbleStep = 0.5;
                let newProgress = Math.max(0, (revert.progress || 0) - progressStep * revert.revertTicks);
                revert.progress = newProgress;
                let currentBubbleValue = (revert.tick || 0) - bubbleStep * revert.revertTicks;
                let newTick = Math.max(0, currentBubbleValue);
                revert.tick = newTick;
                let newCookTime = Math.round((newProgress / 22) * cookTimeTotal);
                keg.setDynamicProperty("cook_time", newCookTime);
                
                const progressItem = new ItemStack("minecraft:stick", 1);
                progressItem.nameTag = `${Math.round(newProgress)}`;
                inv.setItem(7, progressItem);
                let state = bubbleStates.get(keg.id) || { tick: 0 };
                state.tick = newTick;
                bubbleStates.set(keg.id, state);
                updateBubbleBars(inv, keg.id, false, false);
                
                if (newProgress <= 0 && newTick <= 0) {
                    revertStates.delete(keg.id);
                } else {
                    revertStates.set(keg.id, revert);
                }
            } else {
                if (cookTime > 0) {
                    updateCookingProgressBar(inv, cookTime, cookTimeTotal);
                    const progressItem = inv.getItem(7);
                    let progressActive = false;
                    if (progressItem && progressItem.nameTag) {
                        const val = parseInt(progressItem.nameTag);
                        progressActive = val >= 1 && val <= 22;
                    }
                    updateBubbleBars(inv, keg.id, progressActive);
                } else {
                    const progressItem = new ItemStack("minecraft:stick", 1);
                    progressItem.nameTag = "0";
                    inv.setItem(7, progressItem);
                    updateBubbleBars(inv, keg.id, false, true);
                }
                revertStates.delete(keg.id);
            }
        }
        
        // Механика перемещения тары
        const resultItem = inv.getItem(resultSlot);
        if (resultItem) {
            for (let i = 0; i <= 4; i++) {
                let item = inv.getItem(i);
                if (item && isTara(item)) {
                    let amountToMove = item.amount;
                    for (let j = 11; j <= 26 && amountToMove > 0; j++) {
                        let slotItem = inv.getItem(j);
                        if (slotItem && slotItem.typeId === item.typeId && slotItem.amount < slotItem.maxAmount) {
                            const canAdd = Math.min(amountToMove, slotItem.maxAmount - slotItem.amount);
                            slotItem.amount += canAdd;
                            amountToMove -= canAdd;
                            inv.setItem(j, slotItem);
                        }
                    }
                    for (let j = 11; j <= 26 && amountToMove > 0; j++) {
                        if (!inv.getItem(j)) {
                            let newItem = new ItemStack(item.typeId, amountToMove);
                            inv.setItem(j, newItem);
                            amountToMove = 0;
                        }
                    }
                    inv.setItem(i, undefined);
                }
            }
        }
        
        if (!inv.getItem(resultSlot)) {
            const kegLoc = keg.location;
            const players = overworld.getPlayers({
                location: kegLoc,
                maxDistance: 5
            });
            if (players.length > 0) {
                const player = players[0];
                for (let i = 11; i <= 26; i++) {
                    const item = inv.getItem(i);
                    if (item) {
                        player.getComponent("inventory").container.addItem(item);
                        inv.setItem(i, undefined);
                    }
                }
            }
        }
    }
}, 1);

// === УДАЛЕНИЕ ПАЛОК-ПРОГРЕССОВ ИЗ МИРА ===
system.runInterval(() => {
    for (const dimName of ["overworld", "nether", "the_end"]) {
        const dim = world.getDimension(dimName);
        for (const itemEntity of dim.getEntities({ type: "minecraft:item" })) {
            try {
                const itemComp = itemEntity.getComponent("item");
                if (!itemComp) continue;
                const itemStack = itemComp.itemStack;
                if (
                    itemStack.typeId === "minecraft:stick" &&
                    itemStack.nameTag &&
                    !isNaN(itemStack.nameTag) &&
                    Number(itemStack.nameTag) >= 0 &&
                    Number(itemStack.nameTag) <= 22
                ) {
                    itemEntity.kill();
                }
            } catch (e) {}
        }
    }
}, 1);
