"""
演示场景工具
提供各种路径规划演示场景的创建功能
"""

from typing import List, Tuple
import random

def create_simple_grid(rows: int, cols: int) -> List[List[int]]:
    """
    创建简单的空网格
    
    Args:
        rows: 行数
        cols: 列数
        
    Returns:
        网格数据
    """
    return [[0 for _ in range(cols)] for _ in range(rows)]

def create_maze_grid(rows: int, cols: int) -> List[List[int]]:
    """
    创建迷宫网格（使用深度优先搜索算法生成）
    
    Args:
        rows: 行数
        cols: 列数
        
    Returns:
        迷宫网格数据
    """
    # 确保行列数为奇数
    if rows % 2 == 0:
        rows += 1
    if cols % 2 == 0:
        cols += 1
        
    # 初始化网格（全部设为墙）
    grid = [[1 for _ in range(cols)] for _ in range(rows)]
    
    # 使用深度优先搜索生成迷宫
    stack = []
    
    # 起点
    start_row, start_col = 1, 1
    grid[start_row][start_col] = 0
    stack.append((start_row, start_col))
    
    # 方向：上、右、下、左
    directions = [(-2, 0), (0, 2), (2, 0), (0, -2)]
    
    while stack:
        current_row, current_col = stack[-1]
        
        # 获取未访问的邻居
        neighbors = []
        for dr, dc in directions:
            new_row, new_col = current_row + dr, current_col + dc
            if 1 <= new_row < rows - 1 and 1 <= new_col < cols - 1:
                if grid[new_row][new_col] == 1:
                    neighbors.append((new_row, new_col, dr // 2, dc // 2))
                    
        if neighbors:
            # 随机选择一个邻居
            new_row, new_col, wall_row, wall_col = random.choice(neighbors)
            
            # 打通当前单元格和选中邻居之间的墙
            grid[new_row][new_col] = 0
            grid[current_row + wall_row][current_col + wall_col] = 0
            
            # 将选中的邻居加入栈
            stack.append((new_row, new_col))
        else:
            # 回溯
            stack.pop()
            
    return grid

def create_room_grid(rows: int, cols: int) -> List[List[int]]:
    """
    创建房间网格（包含多个房间和走廊）
    
    Args:
        rows: 行数
        cols: 列数
        
    Returns:
        房间网格数据
    """
    grid = [[0 for _ in range(cols)] for _ in range(rows)]
    
    # 添加一些房间（用障碍物围起来的空心矩形）
    rooms = [
        (2, 2, 5, 5),   # (row, col, height, width)
        (2, 10, 5, 5),
        (10, 2, 5, 5),
        (10, 10, 5, 5)
    ]
    
    for room_row, room_col, room_height, room_width in rooms:
        # 创建房间的墙
        for r in range(room_row, min(room_row + room_height, rows)):
            for c in range(room_col, min(room_col + room_width, cols)):
                if (r == room_row or r == room_row + room_height - 1 or 
                    c == room_col or c == room_col + room_width - 1):
                    if 0 <= r < rows and 0 <= c < cols:
                        grid[r][c] = 1
                        
    # 添加走廊连接房间
    # 水平走廊
    for c in range(7, 10):
        if 4 < rows:
            grid[4][c] = 0
            
    # 垂直走廊
    for r in range(7, 10):
        if 4 < cols:
            grid[r][4] = 0
        if 12 < cols:
            grid[r][12] = 0
            
    return grid

def create_random_grid(rows: int, cols: int, obstacle_probability: float = 0.3) -> List[List[int]]:
    """
    创建随机网格
    
    Args:
        rows: 行数
        cols: 列数
        obstacle_probability: 障碍物概率
        
    Returns:
        随机网格数据
    """
    grid = []
    for r in range(rows):
        row = []
        for c in range(cols):
            if random.random() < obstacle_probability:
                row.append(1)  # 障碍物
            else:
                row.append(0)  # 空地
        grid.append(row)
    return grid

def create_tunnel_grid(rows: int, cols: int) -> List[List[int]]:
    """
    创建隧道网格（多条曲折的隧道）
    
    Args:
        rows: 行数
        cols: 列数
        
    Returns:
        隧道网格数据
    """
    grid = [[1 for _ in range(cols)] for _ in range(rows)]  # 全部初始化为墙
    
    # 创建主要隧道
    # 水平隧道
    tunnel_row = rows // 2
    for c in range(1, cols - 1):
        grid[tunnel_row][c] = 0
        
    # 垂直隧道
    tunnel_col = cols // 2
    for r in range(1, rows - 1):
        grid[r][tunnel_col] = 0
        
    # 添加一些分支隧道
    branch_positions = [(tunnel_row, tunnel_col // 4), 
                       (tunnel_row, 3 * tunnel_col // 4),
                       (tunnel_row // 4, tunnel_col),
                       (3 * tunnel_row // 4, tunnel_col)]
                       
    for br, bc in branch_positions:
        # 水平分支
        for c in range(max(1, bc - 3), min(cols - 1, bc + 4)):
            grid[br][c] = 0
        # 垂直分支
        for r in range(max(1, br - 3), min(rows - 1, br + 4)):
            grid[r][bc] = 0
            
    return grid

def get_scenario_names() -> List[str]:
    """
    获取可用场景名称
    
    Returns:
        场景名称列表
    """
    return ["simple", "maze", "room", "random", "tunnel"]

def create_scenario(scenario_name: str, rows: int = 20, cols: int = 20) -> List[List[int]]:
    """
    创建指定场景
    
    Args:
        scenario_name: 场景名称
        rows: 行数
        cols: 列数
        
    Returns:
        网格数据
    """
    if scenario_name == "simple":
        return create_simple_grid(rows, cols)
    elif scenario_name == "maze":
        return create_maze_grid(rows, cols)
    elif scenario_name == "room":
        return create_room_grid(rows, cols)
    elif scenario_name == "random":
        return create_random_grid(rows, cols)
    elif scenario_name == "tunnel":
        return create_tunnel_grid(rows, cols)
    else:
        return create_simple_grid(rows, cols)

def get_suggested_start_goal(scenario_name: str, grid: List[List[int]]) -> Tuple[Tuple[int, int], Tuple[int, int]]:
    """
    获取场景建议的起点和终点
    
    Args:
        scenario_name: 场景名称
        grid: 网格数据
        
    Returns:
        (起点, 终点) 元组
    """
    rows = len(grid)
    cols = len(grid[0]) if rows > 0 else 0
    
    if scenario_name == "simple":
        return (0, 0), (rows - 1, cols - 1)
    elif scenario_name == "maze":
        return (1, 1), (rows - 2, cols - 2)
    elif scenario_name == "room":
        return (0, 0), (rows - 1, cols - 1)
    elif scenario_name == "random":
        # 寻找空地作为起点和终点
        start = None
        goal = None
        for r in range(rows):
            for c in range(cols):
                if grid[r][c] == 0:
                    if start is None:
                        start = (r, c)
                    else:
                        goal = (r, c)
        return start or (0, 0), goal or (rows - 1, cols - 1)
    elif scenario_name == "tunnel":
        return (1, 1), (rows - 2, cols - 2)
    else:
        return (0, 0), (rows - 1, cols - 1)