#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
任务运行记录API模块
提供任务运行记录相关的API接口
"""

import json
from typing import Dict, List, Any, Optional
from fastapi import APIRouter, Query, Path, Request

from routes.common_api import format_response, error_response
from utils.logger import get_logger
from services.task_record_service import TaskRecordService
from routes.model.task_model import SetTaskErrorRequest, SwitchRobotRequest

# 创建路由
router = APIRouter(
    prefix="/api/vwed-task-record",
    tags=["VWED任务运行记录"]
)
# router.add_route
# 设置日志
logger = get_logger("app.task_record_api")

@router.get("/blocks/{task_record_id}")
async def get_task_blocks(
    task_record_id: str = Path(..., description="任务记录ID")
):
    """
    获取指定任务记录下的所有块运行情况
    
    Args:
        task_record_id: 任务记录ID，由run_task接口返回的taskRecordId
        
    Returns:
        包含该任务记录下所有块运行记录的响应
    """
    try:
        result = await TaskRecordService.get_task_blocks(task_record_id)
        if not result["success"]:
            return error_response(message=result["message"], code=500)
        return format_response(data=result["data"], message=result["message"])
    except Exception as e:
        logger.error(f"获取任务块运行情况失败: {str(e)}")
        return error_response(message=f"获取任务块运行情况失败: {str(e)}", code=500)

@router.get("/block/{block_record_id}")
async def get_block_detail(
    block_record_id: str = Path(..., description="块记录ID")
):
    """
    获取指定块记录的详细信息
    
    Args:
        block_record_id: 块记录ID
        
    Returns:
        包含该块记录详细信息的响应
        
    """
    try:
        result = await TaskRecordService.get_block_detail(block_record_id)
        if not result["success"]:
            return error_response(message=result["message"], code=404)
        return format_response(data=result["data"], message=result["message"])
    except Exception as e:
        logger.error(f"获取块记录详情失败: {str(e)}")
        return error_response(message=f"获取块记录详情失败: {str(e)}", code=500)


@router.post("/stop/{task_record_id}")
async def stop_task_definition(task_record_id: str = Path(..., description="任务记录ID")):
    """
    停止指定任务记录下的所有运行任务实例，同时禁用定时任务
    
    Args:
        task_record_id: 任务记录ID
        
    Returns:
        包含停止结果的响应，包括成功停止的任务数量、是否为定时任务等信息
    """
    try:
        # 调用服务层方法
        result = await TaskRecordService.stop_task_record(task_record_id)
        if not result.get("success", False):
            return error_response(
                message=result.get("message", "停止任务失败"), 
                code=400
            )
        return format_response(
            data=result.get("data", {}),
            message=result.get("message", "任务终止成功")
        )
    except Exception as e:
        logger.log_error_with_trace(f"停止任务定义异常", e)
        return error_response(message=f"任务记录终止失败: {str(e)}", code=500)


@router.post("/set-error/{task_record_id}")
async def set_task_error(
    task_record_id: str = Path(..., description="任务记录ID"),
    request_data: SetTaskErrorRequest = None
):
    """
    将指定任务记录及其相关任务块状态设置为错误状态
    
    Args:
        task_record_id: 任务记录ID
        request_data: 请求数据，包含错误原因
        
    Returns:
        包含设置结果的响应，包括任务状态、错误原因、更新的任务块数量等信息
    """
    try:
        logger.info("set-error： 请求参数:"+str(request_data)+", task_record_id:"+str(task_record_id))
        # 获取错误原因
        error_reason = request_data.error_reason if request_data else "未知错误"
        
        # 调用服务层方法
        result = await TaskRecordService.set_task_error(task_record_id, error_reason)
        if not result.get("success", False):
            return error_response(
                message=result.get("message", "设置任务错误状态失败"), 
                code=400
            )
        return format_response(
            data=result.get("data", {}),
            message=result.get("message", "任务状态设置为错误成功")
        )
    except Exception as e:
        logger.error(f"设置任务错误状态异常: {str(e)}")
        return error_response(message=f"设置任务错误状态失败: {str(e)}", code=500)


@router.get("/execution/block/results/{task_record_id}")
async def get_block_result(task_record_id: str = Path(..., description="任务记录ID")):
    """
    获取指定任务记录的执行结果
    
    Args:
        task_record_id: 任务记录ID
        
    Returns:
        包含执行结果的响应
    """
    try:
        result = await TaskRecordService.get_block_results(task_record_id)
        if not result["success"]:
            return error_response(message=result["message"], code=404)
        return format_response(data=result["data"], message=result["message"])
    except Exception as e:
        logger.error(f"获取任务记录执行结果失败: {str(e)}")
        return error_response(message=f"获取任务记录执行结果失败: {str(e)}", code=500)

@router.get("/detail/{task_record_id}")
async def get_task_record_detail(
    task_record_id: str = Path(..., description="任务记录ID")
):
    """
    获取指定任务记录的详细信息
    
    Args:
        task_record_id: 任务记录ID
        
    Returns:
        包含该任务记录详细信息的响应
    """
    try:
        result = await TaskRecordService.get_task_record_detail(task_record_id)
        if not result.get("success", False):
            return error_response(message=result.get("message", "任务记录不存在"), code=404)
        return format_response(data=result.get("data", {}), message="成功获取任务记录详情")
    except Exception as e:
        logger.error(f"获取任务记录详情失败: {str(e)}")
        return error_response(message=f"获取任务记录详情失败: {str(e)}", code=500)


@router.get("/test")
async def test_add_route():
    """
    动态添加路由测试
    """
    # 导入主应用实例
    from app import app
    
    # 定义新的路由处理函数
    def test_handler():
        return {"message": "动态添加的路由成功了!"}
    
    # 直接在应用实例上添加路由
    # 注意：路径必须是绝对路径，包含前缀
    full_path = "/api/vwed-task-record/name"
    
    # 检查路由是否已存在
    route_exists = False
    for route in app.routes:
        if getattr(route, "path", "") == full_path:
            route_exists = True
            break
    
    if not route_exists:
        app.add_api_route(full_path, test_handler, methods=["GET"])
        return {"message": f"路由已添加，请访问 {full_path} 测试"}
    else:
        return {"message": f"路由 {full_path} 已存在"}


@router.post("/switch-robot/{task_record_id}")
async def switch_robot(
    task_record_id: str = Path(..., description="任务记录ID"),
    switch_request: SwitchRobotRequest = None,
    request: Request = None
):
    """
    换机器人接口

    该接口用于在任务执行过程中更换机器人

    处理流程:
    1. 终止原任务所有未完成的块记录,为未执行的块创建终止状态记录
    2. 取消正在执行的任务并清理资源
    3. 根据是否载货选择参数来源并构建新的任务块
    4. 更新任务定义,添加新块到rootBlock,重置任务状态为排队中
    5. 重新提交任务到调度器执行

    支持两种场景:
    1. 未载货(has_cargo=false):
       - 使用原任务定义中的参数(target_site_label、action_task等)
       - 构建新块:选择机器人 → 移动到目标点 → 执行动作

    2. 已载货(has_cargo=true):
       - 使用传入的site_id和action参数
       - site_id会自动识别类型(库位/站点)并构建对应的任务块结构
       - 库位场景:选择机器人 → 获取库位 → 执行通用动作
       - 站点场景:选择机器人 → 移动到站点 → 执行通用动作

    Args:
        task_record_id: 任务记录ID
        switch_request: 换机器人请求参数，包含:
            - robot_name: 机器人名称(可选)
            - robot_group: 机器人组(可选)
            - robot_label_group: 机器人标签组(可选)
            - switch_reason: 更换原因(必填)
            - has_cargo: 是否载货(必填)
            - site_id: 目标库位ID或站点名称(已载货时必填)
            - action: 执行动作(已载货时必填)，如:pick/drop

    Returns:
        包含换机器人结果的响应,包括任务记录ID、换机器人原因、site类型(库位/站点)等信息
    """
    try:
        logger.info(f"换机器人接口调用: task_record_id={task_record_id}, request={switch_request}")

        # 获取客户端信息
        client_ip = request.client.host if request and request.client else None
        user_agent = request.headers.get("user-agent", "") if request else ""
        tf_api_token = request.headers.get("x-access-token") if request else None

        # 构建客户端信息
        client_info = {}
        if request:
            client_info = {
                "user_agent": user_agent,
                "headers": dict(request.headers),
                "method": request.method,
                "url": str(request.url)
            }
        client_info_str = json.dumps(client_info, ensure_ascii=False)

        # 转换请求为字典
        switch_dict = switch_request.model_dump() if switch_request else {}

        # 调用服务层方法
        result = await TaskRecordService.switch_robot(
            task_record_id,
            switch_dict,
            client_ip=client_ip,
            client_info=client_info_str,
            tf_api_token=tf_api_token
        )

        if not result.get("success", False):
            return error_response(
                message=result.get("message", "换机器人失败"),
                code=result.get("code", 400)
            )

        return format_response(
            data=result.get("data", {}),
            message=result.get("message", "换机器人成功")
        )

    except Exception as e:
        logger.error(f"换机器人接口异常: {str(e)}")
        import traceback
        traceback.print_exc()
        return error_response(message=f"换机器人失败: {str(e)}", code=500)


@router.post("/retry/{task_record_id}")
async def retry_failed_task(
    task_record_id: str = Path(..., description="失败的任务记录ID"),
    request: Request = None
):
    """
    重新执行失败的任务

    该接口用于重新执行状态为失败(status=2000)的任务记录
    系统会使用原任务的输入参数重新启动任务

    Args:
        task_record_id: 失败的任务记录ID

    Returns:
        包含新任务记录信息的响应，包括新的taskRecordId
    """
    try:
        # 获取客户端信息
        client_ip = request.client.host if request and request.client else None
        user_agent = request.headers.get("user-agent", "") if request else ""
        tf_api_token = request.headers.get("x-access-token") if request else None

        # 构建客户端信息
        client_info = {}
        if request:
            client_info = {
                "user_agent": user_agent,
                "headers": dict(request.headers),
                "method": request.method,
                "url": str(request.url)
            }
        client_info_str = json.dumps(client_info, ensure_ascii=False)

        # 调用服务层方法执行重发
        result = await TaskRecordService.retry_failed_task(
            task_record_id,
            client_ip=client_ip,
            client_info=client_info_str,
            tf_api_token=tf_api_token
        )

        if not result.get("success", False):
            return error_response(
                message=result.get("message", "任务重发失败"),
                code=result.get("code", 400)
            )

        return format_response(
            data=result.get("data", {}),
            message=result.get("message", "任务重发成功")
        )

    except Exception as e:
        logger.error(f"重发失败任务异常: {str(e)}")
        return error_response(message=f"任务重发失败: {str(e)}", code=500)


@router.get("/remove-route")
async def remove_dynamic_route(route_path: str = Query("/name", description="要删除的路由路径")):
    """
    删除动态添加的路由
    
    Args:
        route_path: 要删除的路由路径，不包含前缀，例如 "/name"
        
    Returns:
        删除结果
    """
    # 导入主应用实例
    from app import app
    from fastapi.routing import APIRoute
    
    # 构建完整路径
    if not route_path.startswith("/"):
        route_path = "/" + route_path
    full_path = f"/api/vwed-task-record{route_path}"
    
    # 查找要删除的路由
    route_found = False
    new_routes = []
    
    for route in app.routes:
        if getattr(route, "path", "") == full_path:
            route_found = True
            continue
        new_routes.append(route)
    
    if route_found:
        # 替换路由列表
        app.router.routes = new_routes
        
        # 重新生成路由查找表
        app.router.routes_by_name = {}
        for route in new_routes:
            if isinstance(route, APIRoute) and route.name:
                app.router.routes_by_name[route.name] = route
        
        return {"success": True, "message": f"路由 {full_path} 已删除"}
    else:
        return {"success": False, "message": f"路由 {full_path} 不存在"}