import { expect } from "@esm-bundle/chai";
import { InventoryContainer } from "../../src/models/InventoryContainer.js";

describe("Model: InventoryContainer", () => {
  let container;

  beforeEach(() => {
    container = new InventoryContainer("TEST_STASH");
  });

  describe("addItem", () => {
    it("should add a new item to the container", () => {
      const item = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: true,
        quantity: 1,
      };

      container.addItem(item);

      expect(container.hasItem("ITEM_RUSTY_BLADE")).to.be.true;
      expect(container.findItem("ITEM_001")).to.deep.equal(item);
    });

    it("should stack consumables with the same defId", () => {
      const potion1 = {
        uid: "ITEM_001",
        defId: "ITEM_HEALTH_POTION",
        isNew: false,
        quantity: 1,
      };

      const potion2 = {
        uid: "ITEM_002",
        defId: "ITEM_HEALTH_POTION",
        isNew: false,
        quantity: 5,
      };

      container.addItem(potion1);
      container.addItem(potion2);

      const found = container.findItem("ITEM_001");
      expect(found).to.exist;
      expect(found.quantity).to.equal(6); // 1 + 5
      expect(container.findItem("ITEM_002")).to.be.null; // Should be merged
    });

    it("should not stack equipment items", () => {
      const sword1 = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      const sword2 = {
        uid: "ITEM_002",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(sword1);
      container.addItem(sword2);

      expect(container.findItem("ITEM_001")).to.exist;
      expect(container.findItem("ITEM_002")).to.exist;
      expect(container.findItem("ITEM_001").quantity).to.equal(1);
      expect(container.findItem("ITEM_002").quantity).to.equal(1);
    });

    it("should cap stackable items at 99", () => {
      const potion1 = {
        uid: "ITEM_001",
        defId: "ITEM_HEALTH_POTION",
        isNew: false,
        quantity: 95,
      };

      const potion2 = {
        uid: "ITEM_002",
        defId: "ITEM_HEALTH_POTION",
        isNew: false,
        quantity: 10,
      };

      container.addItem(potion1);
      container.addItem(potion2);

      const found = container.findItem("ITEM_001");
      expect(found.quantity).to.equal(99); // Capped at 99
      expect(container.findItem("ITEM_002")).to.exist; // Remaining 6 should create new stack
      expect(container.findItem("ITEM_002").quantity).to.equal(6);
    });
  });

  describe("removeItem", () => {
    it("should remove an item by uid", () => {
      const item = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(item);
      expect(container.findItem("ITEM_001")).to.exist;

      container.removeItem("ITEM_001");
      expect(container.findItem("ITEM_001")).to.be.null;
    });

    it("should return the removed item", () => {
      const item = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(item);
      const removed = container.removeItem("ITEM_001");

      expect(removed).to.deep.equal(item);
    });

    it("should return null if item not found", () => {
      const removed = container.removeItem("NONEXISTENT");
      expect(removed).to.be.null;
    });
  });

  describe("hasItem", () => {
    it("should return true if item with defId exists", () => {
      const item = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(item);
      expect(container.hasItem("ITEM_RUSTY_BLADE")).to.be.true;
    });

    it("should return false if item with defId does not exist", () => {
      expect(container.hasItem("ITEM_NONEXISTENT")).to.be.false;
    });
  });

  describe("findItem", () => {
    it("should find item by uid", () => {
      const item = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(item);
      const found = container.findItem("ITEM_001");

      expect(found).to.deep.equal(item);
    });

    it("should return null if item not found", () => {
      const found = container.findItem("NONEXISTENT");
      expect(found).to.be.null;
    });
  });

  describe("getAllItems", () => {
    it("should return all items in the container", () => {
      const item1 = {
        uid: "ITEM_001",
        defId: "ITEM_RUSTY_BLADE",
        isNew: false,
        quantity: 1,
      };

      const item2 = {
        uid: "ITEM_002",
        defId: "ITEM_SCRAP_PLATE",
        isNew: false,
        quantity: 1,
      };

      container.addItem(item1);
      container.addItem(item2);

      const allItems = container.getAllItems();
      expect(allItems).to.have.length(2);
      expect(allItems).to.deep.include(item1);
      expect(allItems).to.deep.include(item2);
    });
  });
});

