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

"""
Modbus配置服务模块
提供Modbus配置相关的服务方法
"""

import uuid
import datetime
from typing import Dict, List, Any, Optional, Union
from sqlalchemy import select, delete, update, and_, func
from pymodbus.client import ModbusTcpClient

from utils.logger import get_logger
from data.models.modbusconfig import VWEDModbusConfig
from data.models.taskdef import VWEDTaskDef
from data.session import get_async_session
from data.enum.modbus_config_enum import ModbusConfigStatus

# 设置日志
logger = get_logger("app.modbus_config_service")

class ModbusConfigService:
    """
    Modbus配置服务类
    提供Modbus配置相关的服务方法
    """
    
    @staticmethod
    async def _check_task_exists(task_id: str) -> bool:
        """
        检查任务ID是否存在

        Args:
            task_id: 任务ID

        Returns:
            任务是否存在
        """
        if not task_id:
            return True  # 如果没有提供任务ID，则视为不需要验证
            
        try:
            async with get_async_session() as session:
                # 查询任务是否存在
                stmt = select(VWEDTaskDef).where(
                    and_(
                        VWEDTaskDef.id == task_id,
                        VWEDTaskDef.is_deleted == False
                    )
                )
                result = await session.execute(stmt)
                task = result.scalars().first()
                
                return task is not None
        except Exception as e:
            logger.error(f"检查任务ID存在性异常: {str(e)}")
            return False
    
    @staticmethod
    async def add_modbus_config(config_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        新增Modbus配置

        Args:
            config_data: Modbus配置信息

        Returns:
            处理结果
        """
        try:
            # 检查任务ID是否存在
            task_id = config_data.get("task_id", "")
            # if task_id:
            async with get_async_session() as session:
                # 查询任务是否存在
                stmt = select(VWEDTaskDef).where(
                    and_(
                        VWEDTaskDef.id == task_id,
                        VWEDTaskDef.is_deleted == False
                    )
                )
                result = await session.execute(stmt)
                task = result.scalars().first()
                if not task:
                    return {
                        "success": False,
                        "message": f"任务ID {task_id} 不存在"
                    }
                else:
                    task_name = task.label
            # else:
            #     return {
            #         "success": False,
            #         "message": f"任务ID 不能为空"
            #     }
            # 创建新的配置对象
            new_config = VWEDModbusConfig(
                id=str(uuid.uuid4()),
                name=config_data.get("name"),
                ip=config_data.get("ip"),
                port=config_data.get("port"),
                slave_id=config_data.get("slave_id"),
                address_type=config_data.get("address_type"),
                address_number=config_data.get("address_number"),
                task_id=task_id,
                task_name=task_name,
                target_value=config_data.get("target_value"),
                remark=config_data.get("remark"),
                status=config_data.get("status", ModbusConfigStatus.START)  # 默认启用
            )
            
            # 额外字段处理
            if "reset_after_trigger" in config_data:
                new_config.reset_after_trigger = config_data.get("reset_after_trigger")
            if "reset_signal_address" in config_data:
                new_config.reset_signal_address = config_data.get("reset_signal_address")
            if "reset_value" in config_data:
                new_config.reset_value = config_data.get("reset_value")
            if "tenant_id" in config_data:
                new_config.tenant_id = config_data.get("tenant_id")
            
            # 保存到数据库
            async with get_async_session() as session:
                session.add(new_config)
                await session.commit()
            
            # 返回结果
            return {
                "success": True,
                "message": "Modbus配置添加成功",
                "data": {
                    "id": new_config.id,
                    "name": new_config.name
                }
            }
        
        except Exception as e:
            logger.error(f"添加Modbus配置异常: {str(e)}")
            return {
                "success": False,
                "message": f"添加Modbus配置异常: {str(e)}"
            }
    
    @staticmethod
    async def delete_modbus_config(config_id: str) -> Dict[str, Any]:
        """
        删除Modbus配置 (软删除)

        Args:
            config_id: 配置ID

        Returns:
            处理结果
        """
        try:
            # 查询配置是否存在
            async with get_async_session() as session:
                # 查询配置
                stmt = select(VWEDModbusConfig).where(
                    and_(
                        VWEDModbusConfig.id == config_id,
                        VWEDModbusConfig.is_deleted == False  # 只查询未删除的记录
                    )
                )
                result = await session.execute(stmt)
                config = result.scalars().first()
                
                if not config:
                    return {
                        "success": False,
                        "message": f"未找到ID为 {config_id} 的Modbus配置"
                    }
                
                # 软删除配置 - 更新is_deleted字段为True
                update_stmt = (
                    update(VWEDModbusConfig)
                    .where(VWEDModbusConfig.id == config_id)
                    .values(is_deleted=True)
                )
                await session.execute(update_stmt)
                await session.commit()
                
                return {
                    "success": True,
                    "message": "Modbus配置删除成功"
                }
        except Exception as e:
            logger.error(f"删除Modbus配置异常: {str(e)}")
            return {
                "success": False,
                "message": f"删除Modbus配置异常: {str(e)}"
            }
    
    @staticmethod
    async def test_modbus_connection(connection_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        测试Modbus连接

        Args:
            connection_data: 连接参数

        Returns:
            连接测试结果
        """
        try:
            
            # 获取连接参数
            ip = connection_data.get("ip")
            port = int(connection_data.get("port"))
            slave_id = int(connection_data.get("slave_id"))
            
            return {
                        "success": True,
                        "message": "Modbus连接测试成功",
                        "data": {
                            "connected": True,
                            "current_value": "1234567890"
                        }
                    }
            # 尝试读取寄存器
            # try:
            #     # 如果提供了地址类型和地址编号，尝试读取指定地址
            #     address_type = connection_data.get("address_type")
            #     address_number = connection_data.get("address_number")
                
            #     if address_type and address_number is not None:
            #         # 根据地址类型选择不同的读取方法
            #         if address_type == "0X":
            #             response = client.read_coils(address_number, 1, slave=slave_id)
            #         elif address_type == "1X":
            #             response = client.read_discrete_inputs(address_number, 1, slave=slave_id)
            #         elif address_type == "3X":
            #             response = client.read_input_registers(address_number, 1, slave=slave_id)
            #         else:  # 默认使用保持寄存器
            #             response = client.read_holding_registers(address_number, 1, slave=slave_id)
            #     else:
            #         # 默认尝试读取保持寄存器的第一个地址
            #         response = client.read_holding_registers(0, 1, slave=slave_id)
                
            #     if response.isError():
            #         return {
            #             "success": False,
            #             "message": f"连接成功，但读取寄存器失败: {response}"
            #         }
            #     else:
            #         # 读取成功，返回当前值
            #         current_value = None
            #         if hasattr(response, 'registers') and response.registers:
            #             current_value = response.registers[0]
            #         elif hasattr(response, 'bits') and response.bits:
            #             current_value = 1 if response.bits[0] else 0
                        
            #         return {
            #             "success": True,
            #             "message": "Modbus连接测试成功",
            #             "data": {
            #                 "connected": True,
            #                 "current_value": current_value
            #             }
            #         }
                
            # except Exception as read_error:
            #     client.close()
            #     return {
            #         "success": False,
            #         "message": f"连接成功，但读取寄存器失败: {str(read_error)}"
            #     }
            
            # # 关闭连接
            # client.close()
            
        except Exception as e:
            logger.error(f"测试Modbus连接异常: {str(e)}")
            return {
                "success": False,
                "message": f"测试Modbus连接异常: {str(e)}"
            }
    
    @staticmethod
    async def update_modbus_config(config_id: str, config_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        修改Modbus配置

        Args:
            config_id: 配置ID
            config_data: 修改后的配置信息

        Returns:
            处理结果
        """
        try:
            # 查询配置是否存在
            async with get_async_session() as session:
                # 查询配置
                stmt = select(VWEDModbusConfig).where(
                    and_(
                        VWEDModbusConfig.id == config_id,
                        VWEDModbusConfig.is_deleted == False  # 只查询未删除的记录
                    )
                )
                result = await session.execute(stmt)
                config = result.scalars().first()
                
                if not config:
                    return {
                        "success": False,
                        "message": f"未找到ID为 {config_id} 的Modbus配置"
                    }
                
                # 检查任务ID是否存在
                task_id = config_data.get("task_id")
                if task_id:
                    async with get_async_session() as session:
                    # 查询任务是否存在
                        stmt = select(VWEDTaskDef).where(
                            and_(
                                VWEDTaskDef.id == task_id,
                                VWEDTaskDef.is_deleted == False
                            )
                        )
                        result = await session.execute(stmt)
                        task = result.scalars().first()
                        if not task:
                            return {
                                "success": False,
                                "message": f"任务ID {task_id} 不存在"
                            }
                        else:
                            task_name = task.label
                else:
                    return {
                        "success": False,
                        "message": f"任务ID 不能为空"
                    }
                
                # 准备更新数据
                update_data = {}
                
                # 检查并添加更新字段
                updatable_fields = [
                    "name", "ip", "port", "slave_id", "address_type", "address_number",
                    "task_id", "target_value", "remark", "task_name"
                ]
                
                has_changes = False
                for field in updatable_fields:
                    if field in config_data:
                        # 获取当前配置数据中的值
                        new_value = config_data[field]
                        # 获取数据库中的现有值
                        current_value = getattr(config, field)
                        
                        # 比较新值和当前值是否相同
                        if new_value != current_value:
                            update_data[field] = new_value
                            has_changes = True
                
                # 如果没有变化，直接返回提示信息
                if not has_changes:
                    return {
                        "success": True,
                        "message": "配置内容未发生变化，无需更新",
                        "data": {"id": config_id}
                    }
                
                # 添加更新时间
                update_data["updated_at"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                update_data["task_name"] = task_name
                # 更新配置
                update_stmt = (
                    update(VWEDModbusConfig)
                    .where(VWEDModbusConfig.id == config_id)
                    .values(**update_data)
                )
                await session.execute(update_stmt)
                await session.commit()
                
                return {
                    "success": True,
                    "message": "Modbus配置更新成功",
                    "data": {"id": config_id}
                }
        except Exception as e:
            logger.error(f"更新Modbus配置异常: {str(e)}")
            return {
                "success": False,
                "message": f"更新Modbus配置异常: {str(e)}"
            }
    
    @staticmethod
    async def get_modbus_config_detail(config_id: str) -> Dict[str, Any]:
        """
        获取Modbus配置详情

        Args:
            config_id: 配置ID

        Returns:
            包含配置详情的结果
        """
        try:
            async with get_async_session() as session:
                # 查询配置
                stmt = select(VWEDModbusConfig).where(
                    and_(
                        VWEDModbusConfig.id == config_id,
                        VWEDModbusConfig.is_deleted == False  # 只查询未删除的记录
                    )
                )
                result = await session.execute(stmt)
                config = result.scalars().first()
                
                if not config:
                    return {
                        "success": False,
                        "message": f"未找到ID为 {config_id} 的Modbus配置"
                    }
                
                # 构建返回数据
                config_data = {
                    "name": config.name,
                    "ip": config.ip,
                    "port": config.port,
                    "slave_id": config.slave_id,
                    "address_type": config.address_type,
                    "address_number": config.address_number,
                    "task_id": config.task_id,
                    "target_value": config.target_value,
                    "remark": config.remark,
                }
                
                return {
                    "success": True,
                    "message": "获取Modbus配置详情成功",
                    "data": config_data
                }
        except Exception as e:
            logger.error(f"获取Modbus配置详情异常: {str(e)}")
            return {
                "success": False,
                "message": f"获取Modbus配置详情异常: {str(e)}"
            }
    
    @staticmethod
    async def get_modbus_config_list(
        page: int, 
        size: int, 
        name: Optional[str] = None, 
        ip: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        获取Modbus配置列表

        Args:
            page: 页码
            size: 每页数量
            name: 配置名称，用于筛选
            ip: 设备IP地址，用于筛选

        Returns:
            包含配置列表的结果
        """
        try:
            async with get_async_session() as session:
                # 构建查询条件
                conditions = [VWEDModbusConfig.is_deleted == False]  # 只查询未删除的记录
                if name:
                    conditions.append(VWEDModbusConfig.name.like(f"%{name}%"))
                if ip:
                    conditions.append(VWEDModbusConfig.ip.like(f"%{ip}%"))
                
                # 查询总数
                count_stmt = select(func.count(VWEDModbusConfig.id)).where(and_(*conditions))
                result = await session.execute(count_stmt)
                total = result.scalar() or 0
                
                # 查询分页数据
                offset = (page - 1) * size
                query_stmt = select(VWEDModbusConfig).where(and_(*conditions)).order_by(VWEDModbusConfig.created_at.desc())
                query_stmt = query_stmt.offset(offset).limit(size)
                result = await session.execute(query_stmt)
                configs = result.scalars().all()
                
                # 构建返回数据 - 使用列表推导式简化代码
                config_list = [{
                    "id": config.id,
                    "name": config.name,
                    "ip": config.ip,
                    "port": config.port,
                    "slave_id": config.slave_id,
                    "address_type": config.address_type,
                    "address_number": config.address_number,
                    "task_id": config.task_id,
                    "task_name": config.task_name,
                    "target_value": config.target_value,
                    "remark": config.remark
                } for config in configs]
                
                return {
                    "success": True,
                    "message": "获取Modbus配置列表成功",
                    "data": {
                        "records": config_list,
                        "total": total,
                        "size": size,
                        "current": page
                    }
                }
        except Exception as e:
            logger.error(f"获取Modbus配置列表异常: {str(e)}")
            return {
                "success": False,
                "message": f"获取Modbus配置列表异常: {str(e)}"
            }
            
    @staticmethod
    async def get_task_modbus_configs(task_id: str) -> Dict[str, Any]:
        """
        获取指定任务关联的Modbus配置列表
        
        Args:
            task_id: 任务ID
            
        Returns:
            包含任务关联的Modbus配置列表的结果
        """
        try:
            async with get_async_session() as session:
                # 查询任务关联的配置
                stmt = select(VWEDModbusConfig).where(
                    and_(
                        VWEDModbusConfig.task_id == task_id,
                        VWEDModbusConfig.status == ModbusConfigStatus.START,  # 只获取启用状态的配置
                        VWEDModbusConfig.is_deleted == False  # 只查询未删除的记录
                    )
                ).order_by(VWEDModbusConfig.created_at.desc())
                
                result = await session.execute(stmt)
                configs = result.scalars().all()
                
                # 构建返回数据 - 使用列表推导式和getattr简化代码
                config_list = [{
                    "id": config.id,
                    "name": config.name,
                    "ip": config.ip,
                    "port": config.port,
                    "slave_id": config.slave_id,
                    "address_type": config.address_type,
                    "address_number": config.address_number,
                    "target_value": config.target_value,
                    # 使用getattr处理可能不存在的字段
                    "reset_after_trigger": getattr(config, "reset_after_trigger", None),
                    "reset_signal_address": getattr(config, "reset_signal_address", None),
                    "reset_value": getattr(config, "reset_value", None)
                } for config in configs]
                
                return {
                    "success": True,
                    "message": "获取任务关联的Modbus配置成功",
                    "data": config_list
                }
        except Exception as e:
            logger.error(f"获取任务关联的Modbus配置异常: {str(e)}")
            return {
                "success": False,
                "message": f"获取任务关联的Modbus配置异常: {str(e)}"
            } 