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

"""
VWED.device 模块 - 设备处理器注册并运行
"""

import asyncio
from typing import Dict, Any, List, Union, Callable
from ..device_handler_service import get_device_service, DeviceType, DeviceBrand, get_protocol_registry
from ..script_registry_service import get_global_registry
from utils.logger import get_logger


class VWEDDeviceModule:
    """VWED.device 模块 - 设备处理器注册并运行"""
    
    def __init__(self, script_id: str):
        self.script_id = script_id
        self.device_service = get_device_service()
        self.registry = get_global_registry()
        self.logger = get_logger(f"script.{script_id}.device")
    
    def register_and_run(self, device_ids: List[str], device_type: Union[str, DeviceType] = DeviceType.VEHICLE,
                        brand_name: str = "huarui", command_type: str = None,
                        handler: Callable = None, description: str = "", 
                        device_brand: str = None, protocol_key: str = None, 
                        auto_encode: bool = True, **kwargs):
        """批量注册并运行设备处理器（新接口）
        
        系统会自动：
        1. 根据设备品牌和类型生成MQTT topics
        2. 订阅相应的topics
        3. 开始监听消息
        4. 消息到达时自动调用处理函数
        5. 自动转发处理结果
        
        使用方式：
        # 批量注册华瑞小车，处理order指令
        VWED.device.register_and_run(
            device_ids=["AGV001", "AGV002", "AGV003"],
            device_type="vehicle",
            brand_name="huarui",
            command_type="order",
            handler=agv_order_processor,
            description="华瑞小车order指令处理器"
        )
        
        # 批量注册仙工小车，处理state指令
        VWED.device.register_and_run(
            device_ids=["SEER001", "SEER002"],
            device_type="vehicle",
            brand_name="seer",
            command_type="state",
            handler=seer_state_processor,
            description="仙工小车state指令处理器"
        )
        
        # 批量注册门设备，处理instantActions指令
        VWED.device.register_and_run(
            device_ids=["DOOR001", "DOOR002"],
            device_type="door",
            brand_name="huarui",
            command_type="instantActions",
            handler=door_processor,
            description="门设备instantActions指令处理器"
        )
        
        Args:
            device_ids: 设备ID列表（必需）- 支持批量注册
            device_type: 设备类型（默认vehicle）
            brand_name: 设备品牌（huarui或seer，默认huarui）
            command_type: 指令类型（必需）- 只能处理一种指令类型，如"order"、"state"、"factsheet"、"instantActions"
            handler: 消息处理函数（必需）
            description: 设备描述信息
            device_brand: 设备品牌（兼容参数，建议使用brand_name）
            protocol_key: 自定义协议标识（已弃用）
            auto_encode: 是否自动编码（已弃用）
            **kwargs: 其他配置参数
        """
        if handler is None:
            raise ValueError("handler参数不能为空")
        
        if not device_ids or len(device_ids) == 0:
            raise ValueError("device_ids参数不能为空")
        
        # 确保device_type是DeviceType枚举
        if isinstance(device_type, str):
            try:
                device_type = DeviceType(device_type)
            except ValueError:
                valid_types = [dt.value for dt in DeviceType]
                raise ValueError(f"device_type参数错误：'{device_type}' 不是有效的设备类型。支持的类型有：{', '.join(valid_types)}")
        
        # 兼容性处理：如果提供了device_brand，使用它覆盖brand_name
        if device_brand is not None:
            brand_name = device_brand
        
        # 过滤已弃用的参数
        filtered_kwargs = {k: v for k, v in kwargs.items() 
                          if k not in ['listen_topics', 'forward_topics', 'protocol_key', 'auto_encode']}
        
        # 调用新的设备服务批量注册接口
        registered_device_ids = self.device_service.register_and_run(
            device_ids=device_ids,
            device_type=device_type,
            brand_name=brand_name,
            command_type=command_type,
            handler=handler,
            script_id=self.script_id,
            description=description,
            **filtered_kwargs
        )
        
        brand_info = f" (品牌: {brand_name})" if brand_name else ""
        self.logger.info(f"设备处理器批量注册成功: {len(registered_device_ids)}个 {device_type.value} 设备{brand_info}")
        return registered_device_ids
        
    def stop_handler(self, device_id: str):
        """停止指定设备处理器的运行"""
        self.device_service.stop_handler(device_id)
        self.logger.info(f"设备处理器已停止: {device_id}")
    
    def restart_handler(self, device_id: str):
        """重启设备处理器"""
        # 获取设备配置
        handler_info = self.registry.get_device_handler(device_id)
        if not handler_info:
            raise ValueError(f"设备处理器不存在: {device_id}")
        
        # 先停止
        self.stop_handler(device_id)
        
        # 重新注册并运行
        self.register_and_run(
            device_id=handler_info["device_id"],
            device_type=handler_info["device_type"],
            listen_topics=handler_info["listen_topics"],
            forward_topics=handler_info["forward_topics"],
            handler=handler_info["handler"],
            description=handler_info["description"]
        )
        
        self.logger.info(f"设备处理器已重启: {device_id}")
    
    def get_running_handlers(self) -> Dict[str, Any]:
        """获取所有正在运行的设备处理器"""
        return self.device_service.get_running_handlers()
    
    def get_handler_status(self, device_id: str) -> Dict[str, Any]:
        """获取设备处理器状态"""
        return self.device_service.get_handler_status(device_id)
    
    async def publish_message(self, topic: str, payload: Any):
        """主动发布MQTT消息
        
        使用方式：
        await VWED.device.publish_message(
            topic="factory/agv/command",
            payload={"action": "move", "x": 100, "y": 200}
        )
        """
        await self.device_service.publish_message(topic, payload)
        self.logger.info(f"MQTT消息已发布: {topic}")
    
    def sync_publish_message(self, topic: str, payload: Any):
        """同步方式发布MQTT消息"""
        asyncio.create_task(self.publish_message(topic, payload))
    
    def subscribe_topic(self, topic: str, handler: Callable):
        """订阅额外的MQTT topic
        
        注意：这是临时订阅，建议使用register_and_run进行完整的设备注册
        """
        # 创建临时设备ID
        temp_device_id = f"temp_{self.script_id}_{topic.replace('/', '_')}"
        
        self.register_and_run(
            device_id=temp_device_id,
            device_type="custom",
            listen_topics=[topic],
            forward_topics=[],
            handler=handler,
            description=f"临时订阅topic: {topic}"
        )
        
        return temp_device_id
    
    def unsubscribe_topic(self, device_id: str):
        """取消订阅topic（通过停止设备处理器）"""
        self.stop_handler(device_id)
    
    def get_device_types(self) -> List[str]:
        """获取支持的设备类型列表"""
        return [dt.value for dt in DeviceType]
    
    def get_device_brands(self) -> List[str]:
        """获取支持的设备品牌列表"""
        return [db.value for db in DeviceBrand]
    