import asyncio
from typing import Dict, Any
EXTERNAL_CALLBACK_URL = "http://roh.vwfawedl.mobi:9001/AGVService/ContainerSendBackRequest" # 生产线到毛坯库任务


async def test1(a: int, b: int) -> int:
    return {"name": a + b}

# def name1(*args, **kwargs):
#     return {"test": "12333"}

async def validate_task_condition(function_args: Dict[str, Any]) -> Dict[str, Any]:
    """
    任务状态验证功能，用于验证关联任务的状态
    
    Args:
        function_args: 包含以下参数的字典
            - task_code: 任务代码，用于查询外部任务记录
            - task_type: 任务类型，用于判断验证逻辑
            - end_node: 终点节点（仅对GT类型任务需要）
    
    Returns:
        Dict[str, Any]: 验证结果
    """
    from services.external_task_record_service import ExternalTaskRecordService
    from services.task_record_service import TaskRecordService
    from data.session import get_async_session
    from data.models.operate_point_layer import OperatePointLayer
    from data.enum.task_record_enum import TaskStatus
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    try:
        # 获取参数
        task_code = function_args.get('task_code')
        task_type = function_args.get('task_type') 
        end_node = function_args.get('end_node')
        
        if not task_code:
            return {
                "success": False,
                "message": "task_code参数为空"
            }
        
        if not task_type:
            return {
                "success": False,
                "message": "task_type参数为空"
            }
        
        # 定义任务类型模板映射
        TASK_TYPE_TEMPLATE_MAPPING = {
            "GG2MP": "GG",
            "GGFK2MP": "GG", 
            "GT2MP": "GT",
            "GTFK2MP": "GT",
            "ZG2MP": "ZG",
            "QZ2MP": "QZ",
            "LG2MP": "LG",
            "PHZ2MP": "PHZ",
            "MP2GG": "GG",
            "MP2GGFK": "GG",
            "MP2GT": "GT", 
            "MP2GTFK": "GT",
            "MP2ZG": "ZG",
            "MP2QZ": "QZ",
            "MP2LG": "LG",
            "MP2PHZ": "PHZ"
        }
        
        # 根据TaskCode查询external_task_record表获取task_record_id
        external_records = await ExternalTaskRecordService.get_task_records_by_task_code(task_code)
        logger.info(f"系统相关记录: {external_records}")
        
        if not external_records:
            return {
                "success": False,
                "message": f"找不到TaskCode={task_code}对应的叫料任务记录，无法监控叫料任务状态"
            }
        
        # 获取最新的记录
        latest_record = max(external_records, key=lambda x: x.created_at)
        
        if not latest_record.task_record_id:
            return {
                "success": False,
                "message": "叫料任务记录对应关键字task_record_id值为空"
            }
        
        # 获取TaskType对应的模板类型
        template_type = TASK_TYPE_TEMPLATE_MAPPING.get(task_type, "")
        logger.info(f"TaskCode={task_code}, TaskType={task_type}, TemplateType={template_type}")
        
        while True:
            try:
                async with get_async_session() as session:
                    # 查询end_node对应的库位锁定状态
                    stmt = select(OperatePointLayer).where(
                        OperatePointLayer.layer_name == end_node,
                        OperatePointLayer.is_deleted == False
                    ).limit(1)
                    result = await session.execute(stmt)
                    end_layer = result.scalar_one_or_none()
                    task_detail_result = await TaskRecordService.get_task_record_detail(
                        latest_record.task_record_id)
                    task_detail = task_detail_result.get("data", {})
                    task_status = task_detail.get("status", "")
                    if task_status == TaskStatus.CANCELED:
                        return {
                            "success": True,
                            "message": f"任务被取消: TaskCode={task_code}, Status={task_status}"
                        }
                    if end_layer:
                        if not end_layer.is_locked:
                            return {
                                "success": True,
                                "message": f"任务验证通过，end_node库位已解锁: {end_node}"
                            }
                        else:
                            logger.info(f"任务，end_node库位被锁定，等待解锁: TaskCode={task_code}, end_node={end_node}, locked_by={end_layer.locked_by}")
                            await asyncio.sleep(2)  # 等待2秒后重试
                    else:
                        logger.warning(f"任务，未找到end_node对应的库位，继续执行: TaskCode={task_code}, end_node={end_node}")
                        return {
                            "success": True,
                            "message": f"任务验证通过，未找到对应库位，继续执行: {end_node}"
                        }

            except Exception as e:
                logger.error(f"任务，检查end_node库位锁定状态时出现异常: {str(e)}, TaskCode={task_code}, end_node={end_node}")
                await asyncio.sleep(2)  # 等待2秒后重试

                    
    except Exception as e:
        logger.error(f"任务状态验证异常: {str(e)}")
        return {
            "success": False,
            "message": f"任务状态验证异常: {str(e)}"
        }


async def call_external_callback(req_code: str, task_type: str, arrival_user: str = "000307" ) -> dict:
    """
    调用外部回调接口

    Args:
        req_code: 到货编号（ReqCode）
        task_type: 任务类型
        arrival_user: 到货用户，固定值 000307

    Returns:
        bool: 调用是否成功（返回result为0）
    """
    arrival_no = req_code
    import aiohttp
    from utils.logger import get_logger
    logger = get_logger("scripts.user_save.test1")
    if task_type not in ["GTFK2MP", "GGFK2MP"]:
        return {"message": "不是返空类型 不需要过账"}

    payload = {
        "arrival_no": arrival_no,
        "arrival_user": arrival_user
    }

    max_retries = 100  # 最大重试次数，防止无限循环
    retry_count = 0

    while retry_count < max_retries:
        try:
            async with aiohttp.ClientSession() as sessions:
                async with sessions.post(EXTERNAL_CALLBACK_URL, json=payload) as response:
                    result = await response.json()
                    logger.info(f"外部接口调用响应: {result}, arrival_no={arrival_no}, 重试次数={retry_count}")

                    # 检查响应结果
                    if result.get("result") == "0":
                        logger.info(f"外部接口调用成功: arrival_no={arrival_no}, 总重试次数={retry_count}")
                        return {"message": "空托盘过账成功！"}
                    elif result.get("result") == "1":
                        logger.info(f"外部接口返回result=1，继续重试: arrival_no={arrival_no}, 重试次数={retry_count}")
                        retry_count += 1
                        await asyncio.sleep(5)  # 等待5秒后重试
                    else:
                        logger.error(f"外部接口返回异常结果: {result}, arrival_no={arrival_no}")
                        retry_count += 1
                        await asyncio.sleep(5)

        except Exception as e:
            logger.error(f"调用外部接口异常: {str(e)}, arrival_no={arrival_no}, 重试次数={retry_count}")
            retry_count += 1
            await asyncio.sleep(5)  # 等待5秒后重试

    logger.error(f"外部接口调用失败，已达到最大重试次数: arrival_no={arrival_no}, 最大重试次数={max_retries}")
    return {"message": "空托盘过账失败，重新尝试次数达到最大值"}


async def get_location(location_list: list, location_key: str) -> dict:
    """
    根据当前库位获取下一个库位站点（轮回逻辑）
    
    Args:
        location_list: 库位列表，格式如 ["1-1", "1-2", "1-3", "1-4"]
        location_key: 当前库位的key，如 "1-2"
    
    Returns:
        str: 下一个库位，如 "1-3"
        
    Example:
        location_list = ["1-1", "1-2", "1-3", "1-4"]
        await get_location(location_list, "1-2")  # 返回 "1-3"
        await get_location(location_list, "1-4")  # 返回 "1-1" (轮回到第一个)
    """
    try:
        if not location_list:
            raise ValueError("location_list不能为空")

        if location_key not in location_list:
            raise ValueError(f"location_key '{location_key}' 不存在于location_list中")
        
        # 找到当前库位在列表中的位置
        current_index = location_list.index(location_key)
        
        # 计算下一个位置的索引（轮回逻辑）
        next_index = (current_index + 1) % len(location_list)
        
        # 返回下一个位置的库位
        next_location_key = location_list[next_index]
        
        return {"next_location_key": next_location_key}
        
    except Exception as e:
        # 如果出现异常，返回错误信息或默认值
        from utils.logger import get_logger
        logger = get_logger("scripts.user_save.test1")
        logger.error(f"get_location函数执行异常: {str(e)}")
        
        # 可以选择抛出异常或返回默认值
        raise ValueError(f"get_location执行失败: {str(e)}")



# print(asyncio.run(get_location(["1-1", "1-2", "1-3", "1-4"], "1-4")))


async def find_movable_vehicle_in_loop(vehicle_list: list, location_list: list) -> dict:
    """
    在环线工区中找到可以移动的小车
    根据库位锁定者来判断小车现在所在位置，并检查前方库位是否可用
    
    Args:
        vehicle_list: 小车名称列表，如 ['amd1', 'amd2', 'amd3']
        location_list: 库位名称列表（按环线顺序），如 ['1-1', '1-2', '1-3', '1-4']
                      环线逻辑：1-1->1-2->1-3->1-4->1-1（循环）
    
    Returns:
        dict: {
            'movable_vehicle': str or None,    # 可以移动的小车名称
            'target_location': str or None,    # 前方可用的库位名称
            'current_location': str or None,   # 当前锁定的库位名称
            'message': str                     # 状态描述
        }
    
    Example:
        vehicle_list = ['amd1', 'amd2', 'amd3']
        location_list = ['1-1', '1-2', '1-3', '1-4']
        result = await find_movable_vehicle_in_loop(vehicle_list, location_list)
        # 返回: {'movable_vehicle': 'amd3', 'target_location': '1-4', 'current_location': '1-3', 'message': '...'}
    """
    from data.session import get_async_session
    from data.models.operate_point_layer import OperatePointLayer
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        if not vehicle_list:
            return {
                'movable_vehicle': None,
                'target_location': None,
                'current_location': None,
                'message': 'vehicle_list参数为空'
            }
        
        if not location_list:
            return {
                'movable_vehicle': None,
                'target_location': None,
                'current_location': None,
                'message': 'location_list参数为空'
            }
        
        async with get_async_session() as session:
            # 1. 找出所有被指定小车锁定的库位，记录每个小车的当前位置
            vehicle_positions = {}  # {vehicle_name: {'location': str, 'location_index': int, 'location_obj': obj}}
            
            # 查询所有库位的锁定情况
            stmt = select(OperatePointLayer).where(
                OperatePointLayer.layer_name.in_(location_list),
                OperatePointLayer.is_deleted == False,
                OperatePointLayer.is_locked == True,
                OperatePointLayer.locked_by.in_(vehicle_list)
            )
            result = await session.execute(stmt)
            locked_locations = result.scalars().all()
            
            # 建立小车位置映射
            for location in locked_locations:
                vehicle_name = location.locked_by
                if location.layer_name in location_list:
                    location_index = location_list.index(location.layer_name)
                    vehicle_positions[vehicle_name] = {
                        'location': location.layer_name,
                        'location_index': location_index,
                        'location_obj': location
                    }
            
            if not vehicle_positions:
                return {
                    'movable_vehicle': None,
                    'target_location': None,
                    'current_location': None,
                    'message': '环线中没有被指定小车锁定的库位'
                }
            
            logger.info(f"当前小车位置: {[(k, v['location']) for k, v in vehicle_positions.items()]}")
            
            # 2. 按环线顺序检查每个小车前方的库位是否可用
            location_count = len(location_list)
            
            for vehicle_name, position_info in vehicle_positions.items():
                current_location_index = position_info['location_index']
                current_location = position_info['location']
                
                # 计算下一个库位位置（环线循环）
                next_location_index = (current_location_index + 1) % location_count
                next_location_name = location_list[next_location_index]
                
                # 检查下一个库位是否被锁定
                stmt = select(OperatePointLayer).where(
                    OperatePointLayer.layer_name == next_location_name,
                    OperatePointLayer.is_deleted == False
                ).limit(1)
                
                result = await session.execute(stmt)
                next_location_obj = result.scalar_one_or_none()
                
                if next_location_obj:
                    if not next_location_obj.is_locked:
                        # 前方库位没有被锁定，说明这个小车可以移动
                        message = f'小车 {vehicle_name} 可以从 {current_location} 移动到 {next_location_name}'
                        logger.info(message)
                        
                        return {
                            'movable_vehicle': vehicle_name,
                            'target_location': next_location_name,
                            'current_location': current_location,
                            'message': message
                        }
                    else:
                        logger.info(f'小车 {vehicle_name} 前方库位 {next_location_name} 被锁定，锁定者: {next_location_obj.locked_by}')
                else:
                    logger.warning(f'未找到库位 {next_location_name}')
            
            return {
                'movable_vehicle': None,
                'target_location': None,
                'current_location': None,
                'message': '环线中所有小车前方库位都被锁定，暂时无法移动'
            }
            
    except Exception as e:
        error_msg = f'查找可移动小车时发生错误: {str(e)}'
        logger.error(error_msg)
        return {
            'movable_vehicle': None,
            'target_location': None,
            'current_location': None,
            'message': error_msg
        }


async def get_all_movable_vehicles_in_loop(vehicle_list: list, location_list: list) -> dict:
    """
    获取环线工区中所有可以移动的小车列表（用于一轮调度3次的场景）
    
    Args:
        vehicle_list: 小车名称列表，如 ['amd1', 'amd2', 'amd3']
        location_list: 库位名称列表（按环线顺序），如 ['1-1', '1-2', '1-3', '1-4']
        
    Returns:
        dict: {
            'movable_vehicles': list,  # [{'vehicle': str, 'target_location': str, 'current_location': str}, ...]
            'total_count': int,        # 可移动小车总数
            'message': str            # 状态描述
        }
    
    Example:
        result = await get_all_movable_vehicles_in_loop(['amd1', 'amd2', 'amd3'], ['1-1', '1-2', '1-3', '1-4'])
        # 返回: {
        #   'movable_vehicles': [
        #     {'vehicle': 'amd3', 'target_location': '1-4', 'current_location': '1-3'},
        #     {'vehicle': 'amd1', 'target_location': '1-2', 'current_location': '1-1'}
        #   ],
        #   'total_count': 2,
        #   'message': '找到2个可移动的小车'
        # }
    """
    from data.session import get_async_session
    from data.models.operate_point_layer import OperatePointLayer
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        movable_vehicles = []
        
        if not vehicle_list or not location_list:
            return {
                'movable_vehicles': [],
                'total_count': 0,
                'message': '参数为空，无法获取可移动小车'
            }
        
        async with get_async_session() as session:
            # 1. 找出所有被指定小车锁定的库位，记录每个小车的当前位置
            vehicle_positions = {}  # {vehicle_name: {'location': str, 'location_index': int, 'location_obj': obj}}
            print("location_list::", location_list)
            print("vehicle_list::", vehicle_list)
            # 查询所有库位的锁定情况
            stmt = select(OperatePointLayer).where(
                OperatePointLayer.layer_name.in_(location_list),
                OperatePointLayer.is_deleted == False,
                OperatePointLayer.is_locked == True,
                OperatePointLayer.locked_by.in_(vehicle_list)
            )
            result = await session.execute(stmt)
            locked_locations = result.scalars().all()
            print(locked_locations, "============")
            # 建立小车位置映射
            for location in locked_locations:
                vehicle_name = location.locked_by
                print(vehicle_name)
                if location.layer_name in location_list:
                    location_index = location_list.index(location.layer_name)
                    vehicle_positions[vehicle_name] = {
                        'location': location.layer_name,
                        'location_index': location_index,
                        'location_obj': location
                    }
            
            if not vehicle_positions:
                return {
                    'movable_vehicles': [],
                    'total_count': 0,
                    'message': '环线中没有被指定小车锁定的库位'
                }
            
            # 2. 检查每个小车前方的库位是否可用
            location_count = len(location_list)
            
            for vehicle_name, position_info in vehicle_positions.items():
                current_location_index = position_info['location_index']
                current_location = position_info['location']
                
                # 计算下一个库位位置（环线循环）
                next_location_index = (current_location_index + 1) % location_count
                next_location_name = location_list[next_location_index]
                
                # 检查下一个库位是否被锁定
                stmt = select(OperatePointLayer).where(
                    OperatePointLayer.layer_name == next_location_name,
                    OperatePointLayer.is_deleted == False
                ).limit(1)
                
                result = await session.execute(stmt)
                next_location_obj = result.scalar_one_or_none()
                
                if next_location_obj and not next_location_obj.is_locked:
                    movable_vehicles.append({
                        'vehicle': vehicle_name,
                        'target_location': next_location_name,
                        'current_location': current_location
                    })
            
            total_count = len(movable_vehicles)
            if total_count > 0:
                vehicle_names = [v['vehicle'] for v in movable_vehicles]
                message = f'找到{total_count}个可移动的小车: {", ".join(vehicle_names)}'
            else:
                message = '环线中所有小车前方库位都被锁定，暂时无法移动'
            
            logger.info(message)
            
            return {
                'movable_vehicles': movable_vehicles[0],
                # 'total_count': total_count,
                # 'message': message
            }
            
    except Exception as e:
        error_msg = f'获取可移动小车列表时发生错误: {str(e)}'
        logger.error(error_msg)
        return {
            'movable_vehicles': [],
            'total_count': 0,
            'message': error_msg
        }


async def judgment_condition(location: str, batteryLevel: float, threshold: float, back_task_id: str, agv_id: str) -> dict:
    """
    判断是否满足执行条件
    
    Args:
        location: 当前位置
        batteryLevel: 电池电量
        threshold: 电量阈值
        back_task_id: 任务模板ID
        agv_id: AGV设备ID
        
    Returns:
        dict: {"bool": True/False}
    """
    from data.session import get_async_session
    from data.models.taskrecord import VWEDTaskRecord
    from data.enum.task_record_enum import TaskStatus
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        # 首先检查位置和电量条件
        if location.find("CP") == -1 or batteryLevel < threshold:
            return {"bool": False}
        
        # 检查是否有相同任务模板的运行任务且AGV相同
        async with get_async_session() as session:
            stmt = select(VWEDTaskRecord).where(
                VWEDTaskRecord.def_id == back_task_id,
                VWEDTaskRecord.agv_id == agv_id,
                VWEDTaskRecord.status == TaskStatus.RUNNING,
                VWEDTaskRecord.is_deleted == False
            )
            result = await session.execute(stmt)
            running_tasks = result.scalars().all()
            
            if running_tasks:
                logger.info(f"发现相同任务模板的运行任务，AGV: {agv_id}, 任务模板: {back_task_id}, 运行任务数量: {len(running_tasks)}")
                return {"bool": False}
            
            logger.info(f"条件检查通过，位置: {location}, 电量: {batteryLevel}, 阈值: {threshold}, AGV: {agv_id}")
            return {"bool": True}
            
    except Exception as e:
        logger.error(f"判断条件时发生错误: {str(e)}")
        return {"bool": False}


async def check_location_lock_status(location_id: str) -> dict:
    """
    查询库位是否被锁定
    
    Args:
        location_id: 库位ID（layer_name字段的值）
        
    Returns:
        dict: {
            "is_locked": bool,         # 是否被锁定
            "locked_by": str or None,  # 锁定者，如果未锁定则为None
            "location_exists": bool,   # 库位是否存在
            "message": str             # 状态描述
        }
    """
    from data.session import get_async_session
    from data.models.operate_point_layer import OperatePointLayer
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        if not location_id:
            return {
                "is_locked": False,
                "locked_by": None,
                "location_exists": False,
                "message": "库位ID参数为空"
            }
        
        async with get_async_session() as session:
            # 查询指定库位的锁定状态
            stmt = select(OperatePointLayer).where(
                OperatePointLayer.layer_name == location_id,
                OperatePointLayer.is_deleted == False
            ).limit(1)
            
            result = await session.execute(stmt)
            location = result.scalar_one_or_none()
            
            if not location:
                logger.warning(f"未找到库位: {location_id}")
                return {
                    "is_locked": False,
                    "locked_by": None,
                    "location_exists": False,
                    "message": f"库位 {location_id} 不存在"
                }
            
            is_locked = bool(location.is_locked)
            locked_by = location.locked_by if is_locked else None
            
            if is_locked:
                message = f"库位 {location_id} 已被锁定，锁定者: {locked_by}"
                logger.info(message)
            else:
                message = f"库位 {location_id} 未被锁定"
                logger.info(message)
            
            return {
                "is_locked": is_locked,
                "locked_by": locked_by,
                "location_exists": True,
                "message": message
            }
            
    except Exception as e:
        error_msg = f"查询库位锁定状态时发生错误: {str(e)}"
        logger.error(error_msg)
        return {
            "is_locked": False,
            "locked_by": None,
            "location_exists": False,
            "message": error_msg
        }


async def unlock_locations_when_last(current_location: str, location_list: list) -> dict:
    """
    检查当前库位是否为库位集合的最后一个，如果是则解锁所有库位
    
    Args:
        current_location: 当前库位名称
        location_list: 按照获取顺序的库位集合列表
        
    Returns:
        dict: {
            "is_last": bool,           # 是否为最后一个库位
            "unlocked": bool,          # 是否执行了解锁操作
            "unlocked_count": int,     # 解锁的库位数量
            "message": str             # 状态描述
        }
    """
    from data.session import get_db
    from services.operate_point_service import OperatePointService
    from routes.model.operate_point_model import BatchStorageLocationStatusUpdateRequest, StorageLocationActionEnum
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        if not current_location:
            return {
                "is_last": False,
                "unlocked": False,
                "unlocked_count": 0,
                "message": "当前库位参数为空"
            }
        
        if not location_list:
            return {
                "is_last": False,
                "unlocked": False,
                "unlocked_count": 0,
                "message": "库位集合列表为空"
            }
        
        # 检查当前库位是否在列表中
        if current_location not in location_list:
            return {
                "is_last": False,
                "unlocked": False,
                "unlocked_count": 0,
                "message": f"当前库位 {current_location} 不在库位集合中"
            }
        
        # 检查是否为最后一个库位
        is_last = current_location == location_list[-1]
        
        if not is_last:
            return {
                "is_last": False,
                "unlocked": False,
                "unlocked_count": 0,
                "message": f"当前库位 {current_location} 不是最后一个库位（最后一个为：{location_list[-1]}）"
            }
        
        # 当前库位是最后一个，执行批量解锁操作
        logger.info(f"当前库位 {current_location} 是最后一个库位，开始解锁所有库位")
        
        try:
            # 创建批量解锁请求对象
            batch_request = BatchStorageLocationStatusUpdateRequest(
                layer_names=location_list,
                action=StorageLocationActionEnum.UNLOCK,
                reason="任务完成，自动解锁所有库位"
            )
            
            # 使用数据库会话调用服务方法
            db = next(get_db())
            try:
                # 调用批量更新库位状态服务
                result = OperatePointService.batch_update_storage_location_status(db, batch_request)
                
                logger.info(f"批量解锁完成：成功 {result.success_count} 个，失败 {result.failed_count} 个")
                
                return {
                    "is_last": True,
                    "unlocked": True,
                    "unlocked_count": result.success_count,
                    "message": f"当前库位是最后一个，已执行批量解锁：成功 {result.success_count} 个库位，失败 {result.failed_count} 个库位"
                }
                
            finally:
                db.close()
                
        except Exception as e:
            logger.error(f"执行批量解锁时发生异常: {str(e)}")
            return {
                "is_last": True,
                "unlocked": False,
                "unlocked_count": 0,
                "message": f"当前库位是最后一个，但解锁操作失败：{str(e)}"
            }
            
    except Exception as e:
        error_msg = f"检查库位和执行解锁时发生错误: {str(e)}"
        logger.error(error_msg)
        return {
            "is_last": False,
            "unlocked": False,
            "unlocked_count": 0,
            "message": error_msg
        }


async def check_vehicle_at_location(vehicle_name: str, location_list: list, vehicle_current_position: str) -> dict:
    """
    检查小车是否在被其锁定的库位对应的站点位置
    
    Args:
        vehicle_name: 小车名称
        location_list: 库位列表
        vehicle_current_position: 小车当前所在的位置/站点
        
    Returns:
        dict: {
            "at_locked_location": bool,     # 是否在被锁定的库位对应站点
            "locked_location": str or None, # 被锁定的库位名称
            "location_station": str or None,# 库位对应的站点名称
            "vehicle_position": str,        # 小车当前位置
            "message": str                  # 状态描述
        }
    """
    from data.session import get_async_session
    from data.models.operate_point_layer import OperatePointLayer
    from sqlalchemy import select
    from utils.logger import get_logger
    
    logger = get_logger("scripts.user_save.test1")
    
    try:
        if not vehicle_name:
            return {
                "at_locked_location": False,
                "locked_location": None,
                "location_station": None,
                "vehicle_position": vehicle_current_position,
                "message": "小车名称参数为空"
            }
        
        if not location_list:
            return {
                "at_locked_location": False,
                "locked_location": None,
                "location_station": None,
                "vehicle_position": vehicle_current_position,
                "message": "库位列表为空"
            }
        
        if not vehicle_current_position:
            return {
                "at_locked_location": False,
                "locked_location": None,
                "location_station": None,
                "vehicle_position": vehicle_current_position,
                "message": "小车当前位置参数为空"
            }
        
        async with get_async_session() as session:
            # 查询库位列表中被当前小车锁定的库位
            stmt = select(OperatePointLayer).where(
                OperatePointLayer.layer_name.in_(location_list),
                OperatePointLayer.is_deleted == False,
                OperatePointLayer.is_locked == True,
                OperatePointLayer.locked_by == vehicle_name
            )
            
            result = await session.execute(stmt)
            locked_locations = result.scalars().all()
            
            if not locked_locations:
                logger.info(f"小车 {vehicle_name} 未锁定库位列表中的任何库位")
                return {
                    "at_locked_location": False,
                    "locked_location": None,
                    "location_station": None,
                    "vehicle_position": vehicle_current_position,
                    "message": f"小车 {vehicle_name} 未锁定库位列表中的任何库位"
                }
            
            # 检查每个被锁定的库位
            for locked_location in locked_locations:
                location_station = locked_location.station_name
                location_layer_name = locked_location.layer_name
                
                logger.info(f"检查小车 {vehicle_name} 锁定的库位 {location_layer_name}，对应站点: {location_station}，小车当前位置: {vehicle_current_position}")
                
                # 检查小车当前位置是否与库位对应的站点匹配
                if vehicle_current_position == location_station:
                    logger.info(f"小车 {vehicle_name} 在被锁定的库位 {location_layer_name} 对应的站点 {location_station}")
                    return {
                        "at_locked_location": False,
                        "locked_location": location_layer_name,
                        "location_station": location_station,
                        "vehicle_position": vehicle_current_position,
                        "message": f"小车 {vehicle_name} 在被锁定的库位 {location_layer_name} 对应的站点 {location_station}"
                    }
            
            # 如果有锁定库位但位置不匹配
            locked_location_info = []
            for locked_location in locked_locations:
                locked_location_info.append(f"{locked_location.layer_name}(站点:{locked_location.station_name})")
            
            message = f"小车 {vehicle_name} 不在被锁定库位的站点，当前位置: {vehicle_current_position}，已锁定库位: {', '.join(locked_location_info)}"
            logger.info(message)
            
            return {
                "at_locked_location": True,
                "locked_location": locked_locations[0].layer_name if locked_locations else None,
                "location_station": locked_locations[0].station_name if locked_locations else None,
                "vehicle_position": vehicle_current_position,
                "message": message
            }
            
    except Exception as e:
        error_msg = f"检查小车位置时发生错误: {str(e)}"
        logger.error(error_msg)
        return {
            "at_locked_location": False,
            "locked_location": None,
            "location_station": None,
            "vehicle_position": vehicle_current_position,
            "message": error_msg
        }


# 测试示例（注释掉的测试代码）
# async def test_movable_functions():
#     """测试可移动小车功能的示例代码"""
#     vehicle_list = ['amd1', 'amd2', 'amd3']
#     action_point_list = ['1-1', '1-2', '1-3', '1-4']
#
#     # 测试找到一个可移动的小车
#     movable = await find_movable_vehicle_in_loop(vehicle_list, action_point_list)
#     print("可移动小车:", movable)
#
#     # 测试获取所有可移动的小车
#     # all_movable = await get_all_movable_vehicles_in_loop(vehicle_list, action_point_list)
#     # print("所有可移动小车:", all_movable)
#
# print(asyncio.run(test_movable_functions()))