const { Player, Inventory } = require("../models");
const DatapackLoader = require("../game/DatapackLoader");
const notificationManager = require("./NotificationManager");

class AdminManager {
  constructor() {
    this.io = null;
  }

  init(io) {
    this.io = io;
  }

  async giveItem(targetName, itemId, amount) {
    const targetPlayer = await Player.findOne({
      where: { username: targetName },
    });
    if (!targetPlayer) throw new Error(`Player '${targetName}' not found.`);

    const itemData = DatapackLoader.getItem(itemId);
    if (!itemData) throw new Error(`Item ID '${itemId}' does not exist.`);

    const [inventoryItem, created] = await Inventory.findOrCreate({
      where: { playerId: targetPlayer.id, itemId: itemId },
      defaults: { quantity: amount },
    });

    if (!created) {
      await inventoryItem.increment("quantity", { by: amount });
    }

    await notificationManager.send({
      playerId: targetPlayer.id,
      type: "item_received",
      title: "Items Received",
      message: `Admin granted you ${amount}x ${itemData.name || itemId}.`,
      data: { itemId, amount },
      priority: "normal",
    });

    this._updatePlayerInventory(targetPlayer.id);
    return { targetName, itemId, amount };
  }

  async clearInventory(targetName) {
    const targetPlayer = await Player.findOne({
      where: { username: targetName },
    });
    if (!targetPlayer) throw new Error(`Player '${targetName}' not found.`);

    await Inventory.destroy({ where: { playerId: targetPlayer.id } });

    await notificationManager.send({
      playerId: targetPlayer.id,
      type: "inventory_clear",
      title: "Inventory Wiped",
      message: "Your inventory has been cleared by an administrator.",
      priority: "high",
    });

    this._updatePlayerInventory(targetPlayer.id, true);
    return targetName;
  }

  async reloadData() {
    DatapackLoader.loadAll();
    if (this.io) {
      this.io.emit("admin:log", "System: Datapacks reloaded by admin.");
    }
  }

  async _updatePlayerInventory(playerId, isEmpty = false) {
    if (!this.io) return;

    const targetSocket = [...this.io.sockets.sockets.values()].find(
      (s) => s.user?.id === playerId,
    );

    if (targetSocket) {
      const items = isEmpty
        ? []
        : await Inventory.findAll({
            where: { playerId },
            attributes: ["itemId", "quantity"],
          });
      targetSocket.emit("player:inventory_data", items);
    }
  }
}

module.exports = new AdminManager();
