import { expect } from "@esm-bundle/chai";
import { RuinGenerator } from "../../src/generation/RuinGenerator.js";
import { VoxelGrid } from "../../src/grid/VoxelGrid.js";

describe("Generation: RuinGenerator", () => {
  let grid;
  let generator;

  beforeEach(() => {
    grid = new VoxelGrid(30, 10, 30);
    generator = new RuinGenerator(grid, 12345);
  });

  it("CoA 1: Should initialize with texture generators and spawn zones", () => {
    expect(generator.floorGen).to.exist;
    expect(generator.wallGen).to.exist;
    expect(generator.generatedAssets).to.have.property("palette");
    expect(generator.generatedAssets).to.have.property("spawnZones");
    expect(generator.generatedAssets.spawnZones).to.have.property("player");
    expect(generator.generatedAssets.spawnZones).to.have.property("enemy");
  });

  it("CoA 2: generate should create rooms", () => {
    generator.generate(5, 4, 8);

    // Should have some air spaces (rooms)
    let airCount = 0;
    for (let x = 0; x < grid.size.x; x++) {
      for (let z = 0; z < grid.size.z; z++) {
        if (grid.getCell(x, 1, z) === 0) {
          airCount++;
        }
      }
    }

    expect(airCount).to.be.greaterThan(0);
  });

  it("CoA 3: generate should mark spawn zones", () => {
    generator.generate(3, 4, 6);

    // Should have spawn zones if rooms were created
    if (generator.generatedAssets.spawnZones.player.length > 0) {
      expect(generator.generatedAssets.spawnZones.player.length).to.be.greaterThan(0);
    }
  });

  it("CoA 4: roomsOverlap should detect overlapping rooms", () => {
    const rooms = [
      { x: 5, z: 5, w: 6, d: 6 },
      { x: 8, z: 8, w: 6, d: 6 }, // Overlaps with first
    ];

    expect(generator.roomsOverlap(rooms[1], rooms)).to.be.true;
  });

  it("CoA 5: roomsOverlap should return false for non-overlapping rooms", () => {
    const rooms = [
      { x: 5, z: 5, w: 4, d: 4 },
    ];
    const newRoom = { x: 15, z: 15, w: 4, d: 4 }; // Far away

    // roomsOverlap checks if newRoom overlaps with any existing room
    expect(generator.roomsOverlap(newRoom, rooms)).to.be.false;
  });

  it("CoA 6: getCenter should calculate room center", () => {
    const room = { x: 10, z: 10, w: 6, d: 8, y: 1 };

    const center = generator.getCenter(room);

    expect(center.x).to.equal(13); // 10 + 6/2 = 13
    expect(center.z).to.equal(14); // 10 + 8/2 = 14
    expect(center.y).to.equal(1);
  });

  it("CoA 7: buildRoom should create floor and walls", () => {
    const room = { x: 5, y: 1, z: 5, w: 6, d: 6 };

    generator.buildRoom(room);

    // Floor should exist
    expect(grid.getCell(7, 0, 7)).to.not.equal(0);

    // Interior should be air
    expect(grid.getCell(7, 1, 7)).to.equal(0);

    // Perimeter should be walls
    expect(grid.getCell(5, 1, 5)).to.not.equal(0); // Corner wall
  });

  it("CoA 8: buildCorridor should connect two points", () => {
    const start = { x: 5, y: 1, z: 5 };
    const end = { x: 15, y: 1, z: 15 };

    generator.buildCorridor(start, end);

    // Path should have floor
    expect(grid.getCell(10, 0, 5)).to.not.equal(0);
    expect(grid.getCell(15, 0, 10)).to.not.equal(0);
  });

  it("CoA 9: markSpawnZone should collect valid floor tiles", () => {
    // Create a room manually
    const room = { x: 5, y: 1, z: 5, w: 6, d: 6 };
    generator.buildRoom(room);

    generator.markSpawnZone(room, "player");

    // Should have some spawn positions
    expect(generator.generatedAssets.spawnZones.player.length).to.be.greaterThan(0);

    // Spawn positions should be valid floor tiles
    const spawn = generator.generatedAssets.spawnZones.player[0];
    expect(grid.getCell(spawn.x, spawn.y - 1, spawn.z)).to.not.equal(0); // Solid below
    expect(grid.getCell(spawn.x, spawn.y, spawn.z)).to.equal(0); // Air at spawn
  });

  it("CoA 10: applyTextures should assign floor and wall IDs", () => {
    // Create a simple structure
    const room = { x: 5, y: 1, z: 5, w: 6, d: 6 };
    generator.buildRoom(room);

    generator.applyTextures();

    // Floor should have IDs 200-209
    const floorId = grid.getCell(7, 1, 7);
    if (floorId !== 0) {
      // If it's a floor surface
      expect(floorId).to.be.greaterThanOrEqual(200);
      expect(floorId).to.be.lessThanOrEqual(209);
    }

    // Wall should have IDs 100-109
    const wallId = grid.getCell(5, 1, 5);
    if (wallId !== 0) {
      expect(wallId).to.be.greaterThanOrEqual(100);
      expect(wallId).to.be.lessThanOrEqual(109);
    }
  });

  it("CoA 11: generate should scatter cover objects", () => {
    generator.generate(3, 4, 6);

    // Check for cover objects (ID 10)
    let coverCount = 0;
    for (let x = 0; x < grid.size.x; x++) {
      for (let z = 0; z < grid.size.z; z++) {
        for (let y = 0; y < grid.size.y; y++) {
          if (grid.getCell(x, y, z) === 10) {
            coverCount++;
          }
        }
      }
    }

    expect(coverCount).to.be.greaterThan(0);
  });
});

