#pragma once

#include <flecs.h>
#include <Ogre.h>


/**
 * @brief Room Layout System - processes Room components and generates cell grid
 * 
 * This system replaces the Lua-based room generation from town.cpp.
 * It processes in order:
 * 1. ClearAreaComponent: Clears cells before generation
 * 2. RoomComponent: Creates floor/ceiling cells and interior walls
 * 3. Room connections: Creates doors between connected rooms
 * 4. Room exits: Creates external walls/doors/windows based on RoomComponent::exits
 * 5. Room windows: Creates windows for rooms with createWindows=true
 * 6. Exterior generation: Converts interior to exterior on outer edges (always runs last)
 * 
 * When ANY component is modified, ALL components are reprocessed to ensure
 * the cell grid is consistent.
 * 
 * The system operates on entities with CellGridComponent (children of Lot/District/Town).
 * Rooms should be children of the CellGrid entity.
 */
class RoomLayoutSystem {
public:
	RoomLayoutSystem(flecs::world& world, Ogre::SceneManager* sceneMgr);
	~RoomLayoutSystem();

	// Initialize the system
	void initialize();

	// Update - process dirty rooms and connections
	void update();

private:
	// Process a single room - creates floor, ceiling, interior walls
	void processRoom(flecs::entity roomEntity, class RoomComponent& room, 
	                 class CellGridComponent& grid);

	// Process connections for a room - creates doors to connected rooms
	void processRoomConnections(flecs::entity roomEntity, class RoomComponent& room,
	                            class CellGridComponent& grid);
	
	// Process a single room connection
	void processRoomConnection(flecs::entity roomAEntity, const class RoomComponent& roomA,
	                           flecs::entity roomBEntity, const class RoomComponent& roomB,
	                           class CellGridComponent& grid);

	// Process room exits - creates external walls/doors/windows
	void processRoomExits(flecs::entity roomEntity, class RoomComponent& room,
	                      class CellGridComponent& grid);

	// Process room windows for a specific room (called after all doors are created)
	void processRoomWindows(flecs::entity roomEntity, class RoomComponent& room,
	                        class CellGridComponent& grid);

	// Process clear area - clears cells before room generation
	void processClearArea(flecs::entity clearEntity, class ClearAreaComponent& clearArea,
	                      class CellGridComponent& grid);

	// Process exterior generation - converts interior walls to exterior on outer edges
	// This always runs at the end of the pipeline for all rooms
	void processExteriorGeneration(class CellGridComponent& grid);

	// Generate furniture for a room based on its tags
	void generateRoomFurniture(class RoomComponent& room, class CellGridComponent& grid);

	// Helper: Get the parent CellGridComponent for an entity
	class CellGridComponent* findParentGrid(flecs::entity entity);

	// Helper: Find the room entity that contains a given cell position
	flecs::entity findRoomAt(flecs::entity gridEntity, int x, int y, int z);

	// Helper: Check if a cell at (x,z) has ANY cell in the grid at the adjacent position
	// side: 0=Z-, 1=Z+, 2=X-, 3=X+
	bool hasAdjacentCell(class CellGridComponent& grid, int x, int y, int z, int side);

	// Helper: Get all cells on the edge of a room on a specific side
	std::vector<std::pair<int, int>> getRoomEdgeCells(const class RoomComponent& room, int side);
	
	// Helper: Get all edge cells (perimeter) of a room - mirrors original roomEdge() function
	std::vector<std::pair<int, int>> getAllEdgeCells(const class RoomComponent& room);

	// Helper: Check if two cells are adjacent
	bool areCellsAdjacent(int x1, int z1, int x2, int z2);

	// Helper: Find adjacent cells between two rooms
	void findAdjacentCells(const class RoomComponent& roomA, const class RoomComponent& roomB,
	                       std::vector<std::pair<int, int>>& outCellsA,
	                       std::vector<std::pair<int, int>>& outCellsB);

	// Helper: Set cell flags for a wall/door/window
	void setWallFlags(class CellGridComponent& grid, int x, int y, int z, 
	                  int side, bool isExternal, bool isDoor, bool isWindow);

	// Helper: Clear wall flags (for creating openings)
	void clearWallFlags(class CellGridComponent& grid, int x, int y, int z, int side);

	flecs::world& m_world;
	Ogre::SceneManager* m_sceneMgr;
	bool m_initialized = false;

	// Queries
	flecs::query<class RoomComponent> m_roomQuery;
	flecs::query<class ClearAreaComponent> m_clearAreaQuery;
	
	// Track if any component was modified - triggers full reprocess
	bool m_needsFullReprocess = false;
	
	// Reprocess all components (called when anything changes)
	void reprocessAll();
};
