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

"""
VWED.robot 模块 - 机器人相关功能
"""

import json
import asyncio
from typing import Dict, Any, Optional, List
from utils.logger import get_logger
from utils.json_parser import safe_parse_dict


class VWEDRobotModule:
    """VWED.robot 模块 - 机器人相关功能"""
    
    def __init__(self, script_id: str):
        self.script_id = script_id
        self.logger = get_logger(f"script.{script_id}.robot")
    
    async def _get_auth_token(self, auto_get_token: bool = True) -> Optional[str]:
        """获取认证token的通用方法
        
        Args:
            auto_get_token: 是否自动获取登录token，默认true
            
        Returns:
            Optional[str]: 认证令牌，获取失败返回None
        """
        if not auto_get_token:
            return None
            
        try:
            from services.sync_service import refresh_token_if_needed
            token = await refresh_token_if_needed()
            if token:
                self.logger.info(f"脚本 {self.script_id} 成功获取到登录token")
                return token
            else:
                self.logger.warning(f"脚本 {self.script_id} 获取登录token失败，继续使用空token")
                return None
        except Exception as e:
            self.logger.warning(f"脚本 {self.script_id} 获取token异常: {str(e)}，继续使用空token")
            return None
    
    async def is_robot_exist(self, robot_name: str) -> bool:
        """校验机器人是否存在
        
        Args:
            robot_name: 机器人名称
            
        Returns:
            bool: True表示存在，False表示不存在
        """
        try:
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用获取AMR列表接口
            from services.sync_service import get_amr_list
            response = await get_amr_list(token)
            
            if response and response.get("success") and response.get("result"):
                # 检查机器人名称是否在列表中
                amr_list = response.get("result", {}).get("records", [])
                for amr in amr_list:
                    if amr.get("name") == robot_name:
                        self.logger.info(f"脚本 {self.script_id} 机器人存在: {robot_name}")
                        return True
                
                self.logger.info(f"脚本 {self.script_id} 机器人不存在: {robot_name}")
                return False
            else:
                self.logger.warning(f"脚本 {self.script_id} 获取机器人信息失败")
                return False
                
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 校验机器人是否存在异常: {str(e)}")
            return False
    
    async def get_lite_robots_status(self) -> str:
        """获取机器人基本信息
        
        Returns:
            str: JSON格式的机器人信息列表
        """
        try:
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用获取AMR列表接口
            from services.sync_service import get_amr_list
            response = await get_amr_list(token)
            
            if response and response.get("success") and response.get("result"):
                amr_list = response.get("result", {}).get("records", [])
                
                # 转换所有字段为蛇形命名
                robots_info = []
                for amr in amr_list:
                    robot_info = {
                        "id": amr.get("id", ""),
                        "tenant_id": amr.get("tenantId", ""),
                        "brand_id": amr.get("brandId", ""),
                        "type_id": amr.get("typeId", ""),
                        "ip_address": amr.get("ipAddress", ""),
                        "name": amr.get("name", ""),
                        "scene_id": amr.get("sceneId", ""),
                        "group_id": amr.get("groupId", ""),
                        "online_station_id": amr.get("onlineStationId", ""),
                        "is_online": amr.get("isOnline", 0),
                        "is_simulation": amr.get("isSimulation", 0),
                        "is_available": amr.get("isAvailable", 0),
                        "is_accept_task": amr.get("isAcceptTask", 0),
                        "length": amr.get("length", 0.0),
                        "width": amr.get("width", 0.0),
                        "min_power": amr.get("minPower", 0),
                        "max_power": amr.get("maxPower", 0),
                        "charge_power": amr.get("chargePower", 0),
                        "task_power": amr.get("taskPower", 0),
                        "exchange_power": amr.get("exchangePower", 0),
                        "amr_status": amr.get("amrStatus", 0),
                        "create_by": amr.get("createBy", ""),
                        "create_time": amr.get("createTime", "")
                    }
                    robots_info.append(robot_info)
                
                result = json.dumps(robots_info, ensure_ascii=False)
                self.logger.info(f"脚本 {self.script_id} 成功获取机器人信息，共 {len(robots_info)} 个机器人")
                return result
            else:
                self.logger.warning(f"脚本 {self.script_id} 获取机器人信息失败")
                return json.dumps([], ensure_ascii=False)
                
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 获取机器人信息异常: {str(e)}")
            return json.dumps([], ensure_ascii=False)
    
    async def get_lite_robots_status_by_id(self, agv_id: str) -> str:
        """根据ID获取机器人基本信息
        
        Args:
            agv_id: 机器人ID
            
        Returns:
            str: JSON格式的机器人信息
        """
        try:
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用获取AMR列表接口
            from services.sync_service import get_amr_list
            response = await get_amr_list(token)
            
            if response and response.get("success") and response.get("result"):
                amr_list = response.get("result", {}).get("records", [])
                
                # 查找指定ID的机器人
                for amr in amr_list:
                    if amr.get("id") == agv_id or amr.get("name") == agv_id:
                        robot_info = {
                            "id": amr.get("id", ""),
                            "tenant_id": amr.get("tenantId", ""),
                            "brand_id": amr.get("brandId", ""),
                            "type_id": amr.get("typeId", ""),
                            "ip_address": amr.get("ipAddress", ""),
                            "name": amr.get("name", ""),
                            "scene_id": amr.get("sceneId", ""),
                            "group_id": amr.get("groupId", ""),
                            "online_station_id": amr.get("onlineStationId", ""),
                            "is_online": amr.get("isOnline", 0),
                            "is_simulation": amr.get("isSimulation", 0),
                            "is_available": amr.get("isAvailable", 0),
                            "is_accept_task": amr.get("isAcceptTask", 0),
                            "length": amr.get("length", 0.0),
                            "width": amr.get("width", 0.0),
                            "min_power": amr.get("minPower", 0),
                            "max_power": amr.get("maxPower", 0),
                            "charge_power": amr.get("chargePower", 0),
                            "task_power": amr.get("taskPower", 0),
                            "exchange_power": amr.get("exchangePower", 0),
                            "amr_status": amr.get("amrStatus", 0),
                            "create_by": amr.get("createBy", ""),
                            "create_time": amr.get("createTime", "")
                        }
                        
                        result = json.dumps(robot_info, ensure_ascii=False)
                        self.logger.info(f"脚本 {self.script_id} 成功获取机器人信息: {agv_id}")
                        return result
                
                # 未找到机器人，返回空对象
                self.logger.warning(f"脚本 {self.script_id} 未找到机器人: {agv_id}")
                return "{}"
            else:
                self.logger.warning(f"脚本 {self.script_id} 获取机器人信息失败")
                return "{}"
                
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 获取机器人信息异常: {str(e)}")
            return "{}"
    
    async def get_vehicle_station(self, agv_id: str) -> str:
        """根据机器人ID获取机器人位置
        
        Args:
            agv_id: 机器人ID
            
        Returns:
            str: JSON格式的位置信息，如果与调度断连返回空对象
        """
        try:
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用获取AMR信息接口
            from services.sync_service import get_amr_info
            response = await get_amr_info(token)
            
            if response and response.get("success") and response.get("result"):
                amr_list = response.get("result", [])
                
                # 查找指定ID的机器人
                for amr in amr_list:
                    if amr.get("id") == agv_id or amr.get("name") == agv_id:
                        station_info = {
                            "last_station": amr.get("lastNodeName", ""),
                            "station": amr.get("lastNodeName", "")
                        }
                        
                        result = json.dumps(station_info, ensure_ascii=False)
                        self.logger.info(f"脚本 {self.script_id} 成功获取机器人位置: {agv_id}")
                        return result
                
                # 未找到机器人，返回空对象
                return "{}"
            else:
                # 与调度断连，返回空对象
                return "{}"
                
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 获取机器人位置异常: {str(e)}")
            return "{}"
    
    async def get_core_alarms(self) -> Optional[str]:
        """获取Core报错信息
        
        Returns:
            Optional[str]: JSON格式的报错信息，断连时返回None
        """
        ## TODO
    
    async def get_core_alarms_by_id(self, code: int) -> Optional[str]:
        """根据ID获取Core报错信息
        
        Args:
            code: 错误码
            
        Returns:
            Optional[str]: JSON格式的报错信息，断连时返回None
        """
        ## TODO
    
    async def get_rbk_alarms(self) -> Optional[str]:
        """获取Rbk报错信息
        
        Returns:
            Optional[str]: JSON格式的报错信息，断连时返回None
        """
        ## TODO
    
    async def get_rbk_alarms_by_id(self, code: int) -> Optional[str]:
        """根据ID获取Rbk报错信息
        
        Args:
            code: 错误码
            
        Returns:
            Optional[str]: JSON格式的报错信息，断连时返回None
        """
        ## TODO
    
    async def set_soft_stop(self, vehicle_id: str, status: bool) -> bool:
        """设置机器人软急停
        
        Args:
            vehicle_id: 机器人名称
            status: True表示设置软急停，False表示取消软急停
            
        Returns:
            bool: True表示成功，False表示失败
        """
        ## TODO
    
    async def get_robots_status(self) -> Optional[str]:
        """获取机器人所有信息
        
        Returns:
            Optional[str]: JSON格式的详细机器人信息，断连时返回None
        """
        ## TODO
    
    async def query_charge_param(self) -> Optional[str]:
        """查询所有机器人充电阈值
        
        Returns:
            Optional[str]: JSON格式的充电阈值信息，断连时返回None
        """
        try:
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用充电参数查询接口
            from services.sync_service import get_amr_charge_params
            response = await get_amr_charge_params(token)
            
            if response and response.get("success") and response.get("result"):
                charge_params = response.get("result", [])
                result = json.dumps(charge_params, ensure_ascii=False)
                self.logger.info(f"脚本 {self.script_id} 成功查询所有机器人充电阈值，共 {len(charge_params)} 个机器人")
                return result
            else:
                self.logger.warning(f"脚本 {self.script_id} 查询所有机器人充电阈值失败")
                return json.dumps([], ensure_ascii=False)
            
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 查询所有机器人充电阈值异常: {str(e)}")
            return None
    
    async def query_charge_param_by_vehicles(self, vehicles: str) -> Optional[str]:
        """查询指定机器人充电阈值
        
        Args:
            vehicles: JSON格式的机器人名称列表字符串
            
        Returns:
            Optional[str]: JSON格式的充电阈值信息
        """
        try:
            # 解析机器人列表
            vehicle_list = json.loads(vehicles) if isinstance(vehicles, str) else vehicles
            
            # 获取认证token
            token = await self._get_auth_token()
            
            # 调用指定机器人充电参数查询接口
            from services.sync_service import get_amr_charge_params_by_vehicles
            response = await get_amr_charge_params_by_vehicles(vehicle_list, token)
            
            if response and response.get("success") and response.get("result"):
                charge_params = response.get("result", [])
                result = json.dumps(charge_params, ensure_ascii=False)
                self.logger.info(f"脚本 {self.script_id} 成功查询指定机器人充电阈值，共 {len(charge_params)} 个机器人")
                return result
            else:
                self.logger.warning(f"脚本 {self.script_id} 查询指定机器人充电阈值失败")
                return json.dumps([], ensure_ascii=False)
            
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 查询指定机器人充电阈值异常: {str(e)}")
            return None
    
    async def modify_charge_param(self, param: str) -> bool:
        """修改机器人充电阈值
        
        Args:
            param: JSON格式的修改参数字符串，包含id（机器人ID或名称）和要修改的充电参数
            
        Returns:
            bool: True表示修改成功，False表示修改失败
        """
        try:
            # 解析修改参数
            param_data = safe_parse_dict(param, self.script_id)
            if param_data is None:
                return False
            
            # 获取机器人ID或名称
            amr_identifier = param_data.get("id")
            if not amr_identifier:
                self.logger.error(f"脚本 {self.script_id} 修改机器人充电阈值失败: 缺少机器人ID")
                return False
            
            # 获取认证token
            token = await self._get_auth_token()
            
            # 首先获取所有AMR信息，找到对应的机器人并获取当前充电参数
            from services.sync_service import get_amr_list
            response = await get_amr_list(token)
            
            if not response or not response.get("success") or not response.get("result"):
                self.logger.warning(f"脚本 {self.script_id} 获取机器人信息失败")
                return False
            
            # 查找对应的机器人，获取真实的ID和当前充电参数
            amr_list = response.get("result", {}).get("records", [])
            actual_amr_id = None
            current_charge_params = None
            
            for amr in amr_list:
                if amr.get("id") == amr_identifier or amr.get("name") == amr_identifier:
                    actual_amr_id = amr.get("id")
                    # 获取当前的充电参数作为默认值
                    current_charge_params = {
                        "exchange_power": amr.get("exchangePower", 0),
                        "task_power": amr.get("taskPower", 0),
                        "charge_power": amr.get("chargePower", 0),
                        "min_power": amr.get("minPower", 0),
                        "max_power": amr.get("maxPower", 0)
                    }
                    break
            
            if not actual_amr_id or current_charge_params is None:
                self.logger.error(f"脚本 {self.script_id} 修改机器人充电阈值失败: 未找到机器人 {amr_identifier}")
                return False
            
            # 准备充电参数 - 从当前参数开始，用用户传入的参数覆盖对应字段
            charge_params = current_charge_params.copy()
            # 蛇形命名字段列表
            snake_fields = ["exchange_power", "task_power", "charge_power", "min_power", "max_power"]
            
            has_changes = False
            # 用用户传入的参数覆盖对应字段
            for snake_field in snake_fields:
                if snake_field in param_data:
                    charge_params[snake_field] = param_data[snake_field]
                    has_changes = True
            
            if not has_changes:
                self.logger.error(f"脚本 {self.script_id} 修改机器人充电阈值失败: 没有要修改的充电参数")
                return False
            
            self.logger.info(f"脚本 {self.script_id} 准备修改机器人 {amr_identifier} 的充电参数: {charge_params}")
            
            # 调用修改充电参数接口，使用真实的机器人ID，传入完整的5个参数
            from services.sync_service import modify_amr_charge_param
            response = await modify_amr_charge_param(actual_amr_id, charge_params, token)
            
            if response and response.get("success"):
                self.logger.info(f"脚本 {self.script_id} 成功修改机器人充电阈值: {amr_identifier} (ID: {actual_amr_id})")
                return True
            else:
                error_msg = response.get("message", "未知错误") if response else "接口调用失败"
                self.logger.warning(f"脚本 {self.script_id} 修改机器人充电阈值失败: {error_msg}")
                return False
            
        except Exception as e:
            self.logger.error(f"脚本 {self.script_id} 修改机器人充电阈值异常: {str(e)}")
            return False