const datapackLoader = require("../../game/DatapackLoader");
const { Inventory } = require("../../models");
const craftManager = require("../../game/CraftManager");

module.exports = (io, socket) => {
  const userId = socket.user?.id;

  const sendStatus = () => {
    const existing = craftManager.getExistingCraft(userId);
    if (existing) {
      socket.emit("player:craft_started", existing);
    }
  };

  socket.on("player:check_active_craft", () => {
    sendStatus();
  });

  socket.on("player:get_recipe_categories", () => {
    try {
      const categories = datapackLoader.getRecipeCategories();
      socket.emit("player:recipe_categories_data", categories);
    } catch (err) {
      console.error(err.message);
    }
  });

  socket.on("player:get_recipes", ({ category }) => {
    try {
      if (!category) return;
      const rawRecipes = datapackLoader.getRecipesByCategory(category);
      const recipeIds = rawRecipes.map((r) => r.id);
      socket.emit("player:recipes_data", { category, recipeIds });
    } catch (err) {
      console.error(err.message);
    }
  });

  socket.on("player:craft_item", async ({ recipeId }) => {
    try {
      if (craftManager.getExistingCraft(userId)) {
        return socket.emit("error", { message: "Already crafting" });
      }

      const recipe = datapackLoader.getRecipe(recipeId);
      if (!recipe) return socket.emit("error", { message: "Recipe not found" });

      for (const ing of recipe.inputs) {
        const itemId = Object.keys(ing)[0];
        const quantity = ing[itemId];
        const invItem = await Inventory.findOne({
          where: { playerId: userId, itemId: itemId },
        });

        if (!invItem || invItem.quantity < quantity) {
          return socket.emit("error", { message: `Not enough resources` });
        }
      }

      for (const ing of recipe.inputs) {
        const itemId = Object.keys(ing)[0];
        const quantity = ing[itemId];
        const invItem = await Inventory.findOne({
          where: { playerId: userId, itemId: itemId },
        });

        if (invItem.quantity === quantity) {
          await invItem.destroy();
        } else {
          await invItem.decrement("quantity", { by: quantity });
        }
      }

      const result = await craftManager.startCraft(userId, recipeId, socket);

      if (result.error) {
        return socket.emit("error", { message: result.error });
      }

      socket.emit("player:craft_started", result);
      socket.emit("player:get_inventory");
    } catch (err) {
      console.error(err.message);
      socket.emit("error", { message: "Internal Crafting Error" });
    }
  });

  sendStatus();
};
