import { describe, it, expect } from 'vitest';
import { idx, inBounds, isWall, isBlocked } from '../world/world-logic';
import { type World, type Tile } from '../../core/types';
import { TileType } from '../../core/terrain';


describe('World Utilities', () => {
  const createTestWorld = (width: number, height: number, tiles: Tile[]): World => ({
    width,
    height,
    tiles,
    actors: new Map(),
    exit: { x: 0, y: 0 }
  });

  describe('idx', () => {
    it('should calculate correct index for 2D coordinates', () => {
      const world = createTestWorld(10, 10, []);
      
      expect(idx(world, 0, 0)).toBe(0);
      expect(idx(world, 5, 0)).toBe(5);
      expect(idx(world, 0, 1)).toBe(10);
      expect(idx(world, 5, 3)).toBe(35);
    });
  });

  describe('inBounds', () => {
    it('should return true for coordinates within bounds', () => {
      const world = createTestWorld(10, 10, []);
      
      expect(inBounds(world, 0, 0)).toBe(true);
      expect(inBounds(world, 5, 5)).toBe(true);
      expect(inBounds(world, 9, 9)).toBe(true);
    });

    it('should return false for coordinates outside bounds', () => {
      const world = createTestWorld(10, 10, []);
      
      expect(inBounds(world, -1, 0)).toBe(false);
      expect(inBounds(world, 0, -1)).toBe(false);
      expect(inBounds(world, 10, 0)).toBe(false);
      expect(inBounds(world, 0, 10)).toBe(false);
      expect(inBounds(world, 11, 11)).toBe(false);
    });
  });

  describe('isWall', () => {
    it('should return true for wall tiles', () => {
      const tiles: Tile[] = new Array(100).fill(TileType.EMPTY);
      tiles[0] = TileType.WALL; // wall at 0,0
      tiles[55] = TileType.WALL; // wall at 5,5

      
      const world = createTestWorld(10, 10, tiles);
      
      expect(isWall(world, 0, 0)).toBe(true);
      expect(isWall(world, 5, 5)).toBe(true);
    });

    it('should return false for floor tiles', () => {
      const tiles: Tile[] = new Array(100).fill(TileType.EMPTY);
      const world = createTestWorld(10, 10, tiles);
      
      expect(isWall(world, 3, 3)).toBe(false);
      expect(isWall(world, 7, 7)).toBe(false);

    });

    it('should return false for out of bounds coordinates', () => {
      const world = createTestWorld(10, 10, new Array(100).fill(0));
      
      expect(isWall(world, -1, 0)).toBe(false);
      expect(isWall(world, 10, 10)).toBe(false);
    });
  });

  describe('isBlocked', () => {
    it('should return true for walls', () => {
      const tiles: Tile[] = new Array(100).fill(TileType.EMPTY);
      tiles[55] = TileType.WALL; // wall at 5,5

      
      const world = createTestWorld(10, 10, tiles);
      
      expect(isBlocked(world, 5, 5)).toBe(true);
    });

    it('should return true for actor positions', () => {
      const world = createTestWorld(10, 10, new Array(100).fill(0));
      world.actors.set(1, {
        id: 1,
        category: "combatant",
        isPlayer: true,
        type: "player",
        pos: { x: 3, y: 3 },
        speed: 100,
        stats: { hp: 10, maxHp: 10, attack: 1, defense: 0 } as any
      });
      
      expect(isBlocked(world, 3, 3)).toBe(true);
    });

    it('should return false for empty floor tiles', () => {
      const world = createTestWorld(10, 10, new Array(100).fill(0));
      
      expect(isBlocked(world, 3, 3)).toBe(false);
      expect(isBlocked(world, 7, 7)).toBe(false);
    });

    it('should return true for out of bounds', () => {
      const world = createTestWorld(10, 10, new Array(100).fill(0));
      
      expect(isBlocked(world, -1, 0)).toBe(true);
      expect(isBlocked(world, 10, 10)).toBe(true);
    });
  });
});
