from builders.text_file_maze_builder import TextFileMazeBuilder
from core.player import Player
from observer.console_view import ConsoleView
from solver.maze_solver import MazeSolver
from strategies.astar_strategy import AStarStrategy
from strategies.bfs_strategy import BFSStrategy
from strategies.dfs_strategy import DFSStrategy
from controller.game_controller import GameController


from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent


def run_demo():
    builder = TextFileMazeBuilder()
    maze = builder.buildFromFile(str(BASE_DIR / "mazes" / "maze_small.txt"))

    view = ConsoleView()
    view.update({"type": "maze_loaded", "message": "Maze loaded"})
    view.render(maze)

    solver = MazeSolver(maze)
    solver.addObserver(view)

    for strategy in (BFSStrategy(), DFSStrategy(), AStarStrategy()):
        solver.setStrategy(strategy)
        stats = solver.solve()

        print()
        print(f"=== {strategy.name} ===")
        print(f"Time: {stats.timeMs:.3f} ms")
        print(f"Visited cells: {stats.visitedCells}")
        print(f"Path length: {stats.pathLength}")
        print(f"Path found: {'yes' if stats.found else 'no'}")

        view.render(maze, path=stats.path)

    player = Player(maze.startCell)
    controller = GameController(maze, player, view)

    print("Manual mode: W/A/S/D move, Z undo, Q quit")
    view.render(maze, player_position=player.currentCell)

    while True:
        cmd = input("Command: ").strip().upper()
        if cmd == "Q":
            break
        if cmd == "Z":
            controller.undo()
        elif cmd in {"W", "A", "S", "D"}:
            controller.move(cmd)
        else:
            print("Unknown command")


if __name__ == "__main__":
    run_demo()
