using BR.AN.PviServices;
using System;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

// 解决 BR.AN.PviServices.Exception 与 System.Exception 的歧义
using Exception = System.Exception;

namespace XP.Hardware.RaySource.Comet
{
    /// <summary>
    /// Comet PVI 通讯客户端静态类
    /// 封装 BR.AN.PviServices 的所有直接调用
    /// 包含：Service/CPU 连接管理、Variable 创建/激活/绑定、ValueChanged 回调处理
    /// </summary>
    public static class CometPviClient
    {
        #region 日志回调委托

        /// <summary>
        /// 日志回调委托（由 .NET 8 层注入）
        /// </summary>
        private static Action<CometLogLevel, string, object[]> _logger;

        #endregion

        #region PVI 核心对象

        private static Service _service;
        private static Cpu _cpu;

        #endregion

        #region 连接参数

        private static string _ipAddress;
        private static int _port;
        private static string _cpuName;
        private static int _sourcePort;
        private static int _stationNumber;

        #endregion

        #region 连接状态

        private static bool _isConnected;
        private static bool _isVariablesConnected;
        private static PviConnectionState _currentConnectionState = PviConnectionState.Disconnected;

        #endregion

        #region PVI 变量 - 电压/电流

        private static Variable _varKVS;   // 设置电压 PC_cmd.r32_TubeVoltage_kV
        private static Variable _varKVR;   // 电压反馈 PLC_stat.r32_TubeVoltage_kV_ist
        private static Variable _varMAS;   // 设置电流 PC_cmd.r32_TubeCurrent_uA
        private static Variable _varMAR;   // 电流反馈 PLC_stat.r32_TubeCurrent_uA_ist

        #endregion

        #region PVI 变量 - 射线开关

        private static Variable _varXonS;   // 开高压 PC_cmd.xrayON
        private static Variable _varXoffS;  // 关高压 PC_cmd.xrayOFF
        private static Variable _varXonR;   // 高压开关反馈 PLC_stat.bo_Xray_on

        #endregion

        #region PVI 变量 - 维护操作（暖机/真空/训机）

        private static Variable _varWarmUpS;   // 暖机设定 PC_cmd.warmUP
        private static Variable _varWarmUpR;   // 暖机状态反馈 PLC_stat.u32_warmup
        private static Variable _varVaconS;    // 真空设定 Vacon
        private static Variable _varVaconR;    // 真空状态反馈 PLC_stat.u32_vacuum
        private static Variable _varVaconRV;   // 真空值 Vac.ist_mbar
        private static Variable _varStartUpS;  // 训机设定 PC_cmd.startUP
        private static Variable _varStartUpR;  // 训机状态反馈 PLC_stat.u32_startup

        #endregion

        #region PVI 变量 - 校准（自动定心/灯丝调整）

        private static Variable _varCurrentKVAutoCenter;  // 当前电压自动定心 PC_cmd.autocentkV
        private static Variable _varALLKVCenter;           // 全部电压自动定心 PC_cmd.autocentALL
        private static Variable _varAutoCenterR;           // 自动定心反馈 PLC_stat.u32_autocenter
        private static Variable _varFilamentAdjust;        // 灯丝调整 PC_cmd.filamentadjust
        private static Variable _varFilamentAdjustR;       // 灯丝调整反馈 PLC_stat.u32_filamentadjust

        #endregion

        #region PVI 变量 - 状态监控

        private static Variable _varInterLockR;   // 连锁状态 Di_Interlock
        private static Variable _varWatchingDog;  // 看门狗 PLC_stat.bo_Watchdog
        private static Variable _varPowerModeR;   // 功率模式反馈 PLC_stat.u32_current_modenumber
        private static Variable _varPowerModeS;   // 功率模式设定 Mode.current_mode_number
        private static Variable _varTxiR;         // TXI 反馈 PLC_stat.bo_TXI
        private static Variable _varTxiOpenS;     // TXI 开启设定 PC_cmd.Ti_reg_on
        private static Variable _varTxiCloseS;    // TXI 关闭设定 PC_cmd.Ti_reg_off

        #endregion

        #region PVI 变量 - 错误监控

        private static Variable _sysErrR;     // 系统错误读取 Sys_error[0]
        private static Variable _sysErrS;     // 系统错误确认 Sys_errorquit
        private static Variable _HSGErrR;     // 高压错误读取 HSG_error[0]
        private static Variable _HSGErrS;     // 高压错误确认 HSG_errorquit
        private static Variable _tubeErrR;    // 管子错误读取 Tube_error[0]
        private static Variable _tubeErrS;    // 管子错误确认 Tube_errorquit
        private static Variable _tubeACErrR;  // 管子真空错误读取 TubeVac_error[0]
        private static Variable _tubeACErrS;  // 管子真空错误确认 Vac_errorquit

        #endregion

        #region 内部缓存状态

        private static float _actualVoltage;
        private static float _actualCurrent;
        private static float _setVoltage;
        private static float _setCurrent;
        private static bool _isXRayOn;
        // 原始 code 码（多语言映射由 .NET 8 侧处理）| Raw code (localization handled by .NET 8 side)
        private static string _warmUpCode = "0";
        private static string _vacuumCode = "0";
        private static string _startUpCode = "0";
        private static string _autoCenterCode = "0";
        private static string _filamentAdjustCode = "0";
        private static bool _isInterlockActive;
        private static string _watchdogStatus = "";
        private static string _powerModeCode = "";
        private static string _txiCode = "False";

        #endregion

        #region 事件通知

        /// <summary>
        /// 状态更新事件（电压、电流、各子系统状态变化时触发）
        /// </summary>
        public static event EventHandler<CometStatusData> StatusChanged;

        /// <summary>
        /// 射线开关状态变更事件
        /// </summary>
        public static event EventHandler<bool> XRayStateChanged;

        /// <summary>
        /// PVI 连接错误事件
        /// </summary>
        public static event EventHandler<string> ErrorOccurred;

        /// <summary>
        /// PVI 连接状态变更事件（未连接、Service已连接、变量已连接）
        /// </summary>
        public static event EventHandler<PviConnectionState> ConnectionStateChanged;

        #endregion

        #region 属性

        /// <summary>
        /// PVI 连接是否已建立
        /// </summary>
        public static bool IsConnected => _isConnected;

        /// <summary>
        /// PVI 变量是否已连接
        /// </summary>
        public static bool IsVariablesConnected => _isVariablesConnected;

        /// <summary>
        /// 当前 PVI 连接状态
        /// </summary>
        public static PviConnectionState CurrentConnectionState => _currentConnectionState;

        #endregion

        #region 日志方法

        /// <summary>
        /// 设置日志回调委托
        /// </summary>
        public static void SetLogger(Action<CometLogLevel, string, object[]> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 内部日志输出辅助方法
        /// 如果未注入日志回调，则静默忽略
        /// </summary>
        private static void Log(CometLogLevel level, string message, params object[] args)
        {
            _logger?.Invoke(level, message, args);
        }

        #endregion

        #region Initialize - PVI Service → CPU 回调链式连接

        /// <summary>
        /// 初始化 PVI Service 和 CPU 连接
        /// </summary>
        public static void Initialize(string ipAddress, int port, string cpuName, int sourcePort, int stationNumber)
        {
            // 保存连接参数
            _ipAddress = ipAddress;
            _port = port;
            _cpuName = cpuName;
            _sourcePort = sourcePort;
            _stationNumber = stationNumber;

            Log(CometLogLevel.Info, $"开始初始化 Comet PVI 连接，IP={ipAddress}, Port={port}, CPU={cpuName}");

            try
            {
                if (_service == null)
                {
                    // 创建 PVI Service 对象并注册回调
                    _service = new Service("service");
                    _service.Connected += new PviEventHandler(Service_Connected);
                    _service.Error += new PviEventHandler(Service_Error);
                }
                _service.Connect();

                Log(CometLogLevel.Info, "PVI Service.Connect() 已调用，等待回调链完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "PVI 连接初始化异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"PVI 连接初始化异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// PVI Service Connected 回调：创建 CPU 对象，设置 TCP/IP 参数，连接 CPU
        /// </summary>
        private static void Service_Connected(object sender, PviEventArgs e)
        {
            Log(CometLogLevel.Info, "PVI Service 连接成功，开始创建 CPU 对象");

            try
            {
                if (_cpu == null)
                {
                    _cpu = new Cpu(_service, _cpuName);
                    _cpu.Connected += new PviEventHandler(Cpu_Connected);
                    _cpu.Connection.DeviceType = DeviceType.TcpIp;
                    _cpu.Connection.TcpIp.DestinationIpAddress = _ipAddress;
                    _cpu.Connection.TcpIp.DestinationPort = (short)_port;
                    _cpu.Connection.TcpIp.SourcePort = (short)_sourcePort;
                    _cpu.Connection.TcpIp.SourceStation = (byte)_stationNumber;
                }
                _cpu.Connect();

                Log(CometLogLevel.Info, $"CPU.Connect() 已调用，目标地址：{_ipAddress}:{_port}");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "创建 CPU 对象异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"创建 CPU 对象异常：{ex.Message}");
            }
        }

        /// <summary>
        /// CPU Connected 回调：确认连接成功，触发连接状态变更事件
        /// </summary>
        private static void Cpu_Connected(object sender, PviEventArgs e)
        {
            try
            {
                _cpu.ReadDateTime();
                _isConnected = true;
                Log(CometLogLevel.Info, "CPU 连接成功，PVI 回调链完成");
                ConnectionStateChanged?.Invoke(null, PviConnectionState.ServiceConnected);
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "CPU 连接确认异常：{0}", ex.Message);
            }
        }

        /// <summary>
        /// PVI Service Error 回调：记录错误并触发错误事件
        /// </summary>
        private static void Service_Error(object sender, PviEventArgs e)
        {
            int errorCode = _service.ErrorCode;
            if (errorCode != 0)
            {
                string errorText = _service.GetErrorText(errorCode);
                Log(CometLogLevel.Error, $"PVI Service 错误，错误码：{errorCode}，错误信息：{errorText}");
                ErrorOccurred?.Invoke(null, $"PVI Service 错误[{errorCode}]：{errorText}");
            }
        }

        #endregion

        #region ConnectVariables - 创建和激活所有 PVI 变量

        /// <summary>
        /// 创建、激活并绑定所有 PVI 变量
        /// </summary>
        public static void ConnectVariables()
        {
            Log(CometLogLevel.Info, "开始创建和连接 PVI 变量");

            try
            {
                // 创建变量
                CreateVariables();

                // 激活变量并连接
                ActivateVariables();

                // 绑定事件处理
                BindEventHandlers();

                _isVariablesConnected = true;
                Log(CometLogLevel.Info, "所有 PVI 变量创建、激活和事件绑定完成");

                // 主动读取一次当前功率模式和 TXI 状态（ValueChanged 仅在值变化时触发）
                // Actively read current power mode and TXI status (ValueChanged only fires on change)
                try
                {
                    if (_varPowerModeR?.Value != null)
                    {
                        _powerModeCode = _varPowerModeR.Value.ToString()?.Trim() ?? "";
                        Log(CometLogLevel.Debug, "初始功率模式原始值: '{0}'", _powerModeCode);
                    }
                    if (_varTxiR?.Value != null)
                    {
                        _txiCode = _varTxiR.Value.ToString() ?? "False";
                    }
                }
                catch (Exception readEx)
                {
                    Log(CometLogLevel.Warn, "初始读取功率模式/TXI状态异常: {0}", readEx.Message);
                }

                ConnectionStateChanged?.Invoke(null, PviConnectionState.VariablesConnected);
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "PVI 变量连接异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"PVI 变量连接异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 创建所有 PVI Variable 对象
        /// </summary>
        private static void CreateVariables()
        {
            // 电压/电流
            _varKVS = new Variable(_cpu, "PC_cmd.r32_TubeVoltage_kV");
            _varKVR = new Variable(_cpu, "PLC_stat.r32_TubeVoltage_kV_ist");
            _varMAS = new Variable(_cpu, "PC_cmd.r32_TubeCurrent_uA");
            _varMAR = new Variable(_cpu, "PLC_stat.r32_TubeCurrent_uA_ist");

            // 射线开关
            _varXonS = new Variable(_cpu, "PC_cmd.xrayON");
            _varXoffS = new Variable(_cpu, "PC_cmd.xrayOFF");
            _varXonR = new Variable(_cpu, "PLC_stat.bo_Xray_on");

            // 暖机
            _varWarmUpS = new Variable(_cpu, "PC_cmd.warmUP");
            _varWarmUpR = new Variable(_cpu, "PLC_stat.u32_warmup");

            // 真空
            _varVaconS = new Variable(_cpu, "Vacon");
            _varVaconR = new Variable(_cpu, "PLC_stat.u32_vacuum");
            _varVaconRV = new Variable(_cpu, "Vac.ist_mbar");

            // 训机
            _varStartUpS = new Variable(_cpu, "PC_cmd.startUP");
            _varStartUpR = new Variable(_cpu, "PLC_stat.u32_startup");

            // 自动定心
            _varCurrentKVAutoCenter = new Variable(_cpu, "PC_cmd.autocentkV");
            _varALLKVCenter = new Variable(_cpu, "PC_cmd.autocentALL");
            _varAutoCenterR = new Variable(_cpu, "PLC_stat.u32_autocenter");

            // 灯丝调整
            _varFilamentAdjust = new Variable(_cpu, "PC_cmd.filamentadjust");
            _varFilamentAdjustR = new Variable(_cpu, "PLC_stat.u32_filamentadjust");

            // 状态监控
            _varInterLockR = new Variable(_cpu, "Di_Interlock");
            _varWatchingDog = new Variable(_cpu, "PLC_stat.bo_Watchdog");
            _varPowerModeR = new Variable(_cpu, "PLC_stat.u32_current_modenumber");
            _varPowerModeS = new Variable(_cpu, "Mode.current_mode_number");
            _varTxiR = new Variable(_cpu, "PLC_stat.bo_TXI");
            _varTxiOpenS = new Variable(_cpu, "PC_cmd.Ti_reg_on");
            _varTxiCloseS = new Variable(_cpu, "PC_cmd.Ti_reg_off");

            // 错误监控
            _sysErrR = new Variable(_cpu, "Sys_error[0]");
            _sysErrS = new Variable(_cpu, "Sys_errorquit");
            _HSGErrR = new Variable(_cpu, "HSG_error[0]");
            _HSGErrS = new Variable(_cpu, "HSG_errorquit");
            _tubeErrR = new Variable(_cpu, "Tube_error[0]");
            _tubeErrS = new Variable(_cpu, "Tube_errorquit");
            _tubeACErrR = new Variable(_cpu, "TubeVac_error[0]");
            _tubeACErrS = new Variable(_cpu, "Vac_errorquit");

            Log(CometLogLevel.Info, "所有 PVI 变量对象创建完成");
        }

        /// <summary>
        /// 激活所有变量并调用 Connect
        /// </summary>
        private static void ActivateVariables()
        {
            Variable[] allVariables = {
                _varKVS, _varKVR, _varMAS, _varMAR,
                _varXonS, _varXoffS, _varXonR,
                _varWarmUpS, _varWarmUpR,
                _varVaconS, _varVaconR, _varVaconRV,
                _varStartUpS, _varStartUpR,
                _varCurrentKVAutoCenter, _varALLKVCenter, _varAutoCenterR,
                _varFilamentAdjust, _varFilamentAdjustR,
                _varInterLockR, _varWatchingDog,
                _varPowerModeR, _varPowerModeS, _varTxiR,
                _varTxiOpenS, _varTxiCloseS,
                _sysErrR, _sysErrS,
                _HSGErrR, _HSGErrS,
                _tubeErrR, _tubeErrS,
                _tubeACErrR, _tubeACErrS
            };

            foreach (var variable in allVariables)
            {
                variable.Active = true;
                variable.Connect();
            }

            Log(CometLogLevel.Info, "所有 PVI 变量已激活并连接");
        }

        /// <summary>
        /// 为所有反馈类变量绑定 ValueChanged 事件处理程序
        /// </summary>
        private static void BindEventHandlers()
        {
            // 电压/电流反馈
            _varKVR.ValueChanged += new VariableEventHandler(VarKVR_ValueChanged);
            _varMAR.ValueChanged += new VariableEventHandler(VarMAR_ValueChanged);

            // 电压/电流设定值反馈（用于同步滑块显示）| Set value feedback (for slider sync)
            _varKVS.ValueChanged += new VariableEventHandler(VarKVS_ValueChanged);
            _varMAS.ValueChanged += new VariableEventHandler(VarMAS_ValueChanged);

            // 射线开关反馈
            _varXonR.ValueChanged += new VariableEventHandler(VarXonR_ValueChanged);

            // 暖机反馈
            _varWarmUpR.ValueChanged += new VariableEventHandler(VarWarmUpR_ValueChanged);

            // 真空反馈
            _varVaconR.ValueChanged += new VariableEventHandler(VarVaconR_ValueChanged);

            // 训机反馈
            _varStartUpR.ValueChanged += new VariableEventHandler(VarStartUpR_ValueChanged);

            // 自动定心反馈
            _varAutoCenterR.ValueChanged += new VariableEventHandler(VarAutoCenterR_ValueChanged);

            // 灯丝调整反馈
            _varFilamentAdjustR.ValueChanged += new VariableEventHandler(VarFilamentAdjustR_ValueChanged);

            // 连锁状态
            _varInterLockR.ValueChanged += new VariableEventHandler(VarInterLockR_ValueChanged);

            // 看门狗
            _varWatchingDog.ValueChanged += new VariableEventHandler(VarWatchingDog_ValueChanged);

            // 功率模式
            _varPowerModeR.ValueChanged += new VariableEventHandler(VarPowerModeR_ValueChanged);

            // TXI
            _varTxiR.ValueChanged += new VariableEventHandler(VarTxiR_ValueChanged);

            Log(CometLogLevel.Info, "所有反馈类变量 ValueChanged 事件已绑定");
        }

        #endregion

        #region ValueChanged 回调处理方法

        private static void VarKVR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _actualVoltage = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
            PublishStatusUpdate();
        }

        private static void VarMAR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _actualCurrent = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
            PublishStatusUpdate();
        }

        private static void VarKVS_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _setVoltage = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
            PublishStatusUpdate();
        }

        private static void VarMAS_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _setCurrent = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
            PublishStatusUpdate();
        }

        private static void VarXonR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _isXRayOn = bool.Parse(v.Value.ToString());
            XRayStateChanged?.Invoke(null, _isXRayOn);
            PublishStatusUpdate();
        }

        private static void VarWarmUpR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _warmUpCode = v.Value?.ToString() ?? "0";
            PublishStatusUpdate();
        }

        private static void VarVaconR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _vacuumCode = v.Value?.ToString() ?? "0";
            PublishStatusUpdate();
        }

        private static void VarStartUpR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _startUpCode = v.Value?.ToString() ?? "0";
            PublishStatusUpdate();
        }

        private static void VarAutoCenterR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _autoCenterCode = v.Value?.ToString() ?? "0";
            PublishStatusUpdate();
        }

        private static void VarFilamentAdjustR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _filamentAdjustCode = v.Value?.ToString() ?? "0";
            PublishStatusUpdate();
        }

        private static void VarInterLockR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            string val = v.Value.ToString();
            _isInterlockActive = val == "True";
            PublishStatusUpdate();
        }

        private static void VarWatchingDog_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _watchdogStatus = v.Value.ToString();
            // 注意：看门狗不触发 PublishStatusUpdate
        }

        private static void VarPowerModeR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _powerModeCode = v.Value?.ToString()?.Trim() ?? "";
            Log(CometLogLevel.Debug, "功率模式原始值: '{0}'", _powerModeCode);
            PublishStatusUpdate();
        }

        private static void VarTxiR_ValueChanged(object sender, VariableEventArgs e)
        {
            Variable v = (Variable)sender;
            _txiCode = v.Value?.ToString() ?? "False";
            PublishStatusUpdate();
        }

        /// <summary>
        /// 构建状态数据并触发 StatusChanged 事件
        /// </summary>
        private static void PublishStatusUpdate()
        {
            StatusChanged?.Invoke(null, BuildStatusData());
        }

        /// <summary>
        /// 构建当前状态数据快照
        /// </summary>
        private static CometStatusData BuildStatusData()
        {
            return new CometStatusData
            {
                SetVoltage = _setVoltage,
                ActualVoltage = _actualVoltage,
                SetCurrent = _setCurrent,
                ActualCurrent = _actualCurrent,
                IsXRayOn = _isXRayOn,
                WarmUpStatus = _warmUpCode,
                VacuumStatus = _vacuumCode,
                StartUpStatus = _startUpCode,
                AutoCenterStatus = _autoCenterCode,
                FilamentAdjustStatus = _filamentAdjustCode,
                IsInterlockActive = _isInterlockActive,
                WatchdogStatus = _watchdogStatus,
                PowerMode = _powerModeCode,
                TxiStatus = _txiCode
            };
        }

        #endregion

        #region 状态码映射方法

        /// <summary>
        /// 暖机状态码映射
        /// </summary>
        internal static string MapWarmUpStatus(string code)
        {
            switch (code)
            {
                case "0": return "初始状态";
                case "1": return "暖机中";
                case "2": return "暖机完成到最大电压";
                case "3": return "暖机因故障失败";
                case "33": return "需要暖机";
                default: return "未知状态";
            }
        }

        /// <summary>
        /// 真空状态码映射
        /// </summary>
        internal static string MapVacuumStatus(string code)
        {
            switch (code)
            {
                case "0": return "初始状态";
                case "1": return "抽真空中";
                case "2": return "真空准备好";
                case "22": return "真空值<1e-5mbar";
                case "30": return "真空泵未使能";
                case "40": return "真空泵通风能";
                default: return "未知状态";
            }
        }

        /// <summary>
        /// 训机状态码映射
        /// </summary>
        internal static string MapStartUpStatus(string code)
        {
            switch (code)
            {
                case "0": return "初始状态";
                case "1": return "训机中";
                case "2": return "训机完成";
                case "3": return "训机因故障失败";
                default: return "未知状态";
            }
        }

        /// <summary>
        /// 自动定心状态码映射
        /// </summary>
        internal static string MapAutoCenterStatus(string code)
        {
            switch (code)
            {
                case "0": return "初始状态";
                case "1": return "自动定心中";
                case "2": return "自动定心完成";
                case "3": return "定心因故障失败";
                default: return "未知状态";
            }
        }

        /// <summary>
        /// 灯丝调整状态码映射
        /// </summary>
        internal static string MapFilamentAdjustStatus(string code)
        {
            switch (code)
            {
                case "0": return "初始状态";
                case "1": return "灯丝校准中";
                case "2": return "灯丝校准完成";
                case "3": return "灯丝校准因故障失败";
                case "33": return "需要灯丝校准";
                default: return "未知状态";
            }
        }

        /// <summary>
        /// 功率模式映射
        /// </summary>
        internal static string MapPowerMode(string value)
        {
            // PVI 变量可能返回带空格或小数的值，统一处理 | PVI variable may return value with spaces or decimals
            var trimmed = (value ?? "").Trim();

            // 尝试解析为数字后再比较 | Try parsing as number before comparing
            if (int.TryParse(trimmed, out var intVal))
            {
                switch (intVal)
                {
                    case 1: return "Micro Focus";
                    case 2: return "High Power";
                }
            }
            else if (double.TryParse(trimmed, out var dblVal))
            {
                switch ((int)dblVal)
                {
                    case 1: return "Micro Focus";
                    case 2: return "High Power";
                }
            }

            return $"Unknown({trimmed})";
        }

        /// <summary>
        /// TXI 状态映射
        /// </summary>
        internal static string MapTxiStatus(string value)
        {
            switch (value)
            {
                case "True": return "TXI is on";
                case "False": return "TXI is off";
                default: return "未知状态";
            }
        }

        #endregion

        #region 射线控制和参数设置方法

        /// <summary>
        /// 开启高压
        /// </summary>
        public static void TurnOn()
        {
            Log(CometLogLevel.Info, "执行 TurnOn 操作");
            try
            {
                _varXonS.Value = "True";
                _varXonS.WriteValue();
                Log(CometLogLevel.Info, "TurnOn 操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "TurnOn 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"TurnOn 操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 关闭高压
        /// </summary>
        public static void TurnOff()
        {
            Log(CometLogLevel.Info, "执行 TurnOff 操作");
            try
            {
                _varXoffS.Value = "True";
                _varXoffS.WriteValue();
                Log(CometLogLevel.Info, "TurnOff 操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "TurnOff 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"TurnOff 操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 设置电压（kV）
        /// </summary>
        public static void SetVoltage(float voltage)
        {
            Log(CometLogLevel.Info, "执行 SetVoltage 操作，目标电压：{0}kV", voltage);
            try
            {
                _varKVS.Value = voltage.ToString();
                _varKVS.WriteValue();
                _setVoltage = voltage;
                Log(CometLogLevel.Info, "SetVoltage 操作完成，电压：{0}kV", voltage);
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "SetVoltage 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"SetVoltage 操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 设置电流（μA）
        /// </summary>
        public static void SetCurrent(float current)
        {
            Log(CometLogLevel.Info, "执行 SetCurrent 操作，目标电流：{0}μA", current);
            try
            {
                _varMAS.Value = current.ToString();
                _varMAS.WriteValue();
                _setCurrent = current;
                Log(CometLogLevel.Info, "SetCurrent 操作完成，电流：{0}μA", current);
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "SetCurrent 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"SetCurrent 操作异常：{ex.Message}");
                throw;
            }
        }

        public static void SetWatchDog()
        {
            if (_cpu != null)
            {
                if (_cpu.IsConnected)
                {
                    if (_isVariablesConnected)
                    {
                        _varWatchingDog.Value = "0";
                        _varWatchingDog.WriteValue();
                    }
                }
            }
        }

        /// <summary>
        /// TXI 开启
        /// </summary>
        public static void TxiOn()
        {
            Log(CometLogLevel.Info, "执行 TXI ON 操作");
            try
            {
                _varTxiOpenS.Value = "True";
                _varTxiOpenS.WriteValue();
                Log(CometLogLevel.Info, "TXI ON 操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "TXI ON 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"TXI ON 操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// TXI 关闭
        /// </summary>
        public static void TxiOff()
        {
            Log(CometLogLevel.Info, "执行 TXI OFF 操作");
            try
            {
                _varTxiCloseS.Value = "True";
                _varTxiCloseS.WriteValue();
                Log(CometLogLevel.Info, "TXI OFF 操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "TXI OFF 操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"TXI OFF 操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 暖机设置
        /// </summary>
        public static void WarmUp()
        {
            Log(CometLogLevel.Info, "执行暖机设置操作");
            try
            {
                _varWarmUpS.Value = "True";
                _varWarmUpS.WriteValue();
                Log(CometLogLevel.Info, "暖机设置操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "暖机设置操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"暖机设置操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 训机设置
        /// </summary>
        public static void Training()
        {
            Log(CometLogLevel.Info, "执行训机设置操作");
            try
            {
                _varStartUpS.Value = "True";
                _varStartUpS.WriteValue();
                Log(CometLogLevel.Info, "训机设置操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "训机设置操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"训机设置操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 灯丝校准
        /// </summary>
        public static void FilamentCalibration()
        {
            Log(CometLogLevel.Info, "执行灯丝校准操作");
            try
            {
                _varFilamentAdjust.Value = "True";
                _varFilamentAdjust.WriteValue();
                Log(CometLogLevel.Info, "灯丝校准操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "灯丝校准操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"灯丝校准操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 全部电压自动定心
        /// </summary>
        public static void AutoCenter()
        {
            Log(CometLogLevel.Info, "执行全部电压自动定心操作");
            try
            {
                _varALLKVCenter.Value = "True";
                _varALLKVCenter.WriteValue();
                Log(CometLogLevel.Info, "全部电压自动定心操作完成");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "全部电压自动定心操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"全部电压自动定心操作异常：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 设置功率模式
        /// </summary>
        /// <param name="mode">功率模式值：1=Micro Focus，2=High Power</param>
        public static void SetPowerMode(int mode)
        {
            Log(CometLogLevel.Info, "执行设置功率模式操作，Mode={0}", mode);
            try
            {
                _varPowerModeS.Value = mode.ToString();
                _varPowerModeS.WriteValue();
                Log(CometLogLevel.Info, "设置功率模式操作完成，Mode={0}", mode);
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Error, "设置功率模式操作异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"设置功率模式操作异常：{ex.Message}");
                throw;
            }
        }

        #endregion

        #region 状态读取方法

        /// <summary>
        /// 读取实际电压反馈值
        /// </summary>
        public static float ReadVoltage()
        {
            return _actualVoltage;
        }

        /// <summary>
        /// 读取实际电流反馈值
        /// </summary>
        public static float ReadCurrent()
        {
            return _actualCurrent;
        }

        /// <summary>
        /// 读取完整系统状态
        /// </summary>
        public static CometStatusData ReadSystemStatus()
        {
            return BuildStatusData();
        }

        /// <summary>
        /// 读取连接状态
        /// </summary>
        /// <returns>true=已连接，false=未连接</returns>
        public static bool ReadRaySourceConnectStatus()
        {
            PviConnectionState newState = PviConnectionState.Disconnected;
            bool result = false;

            if (_cpu != null)
            {
                if (_cpu.IsConnected && _isVariablesConnected)
                {
                    newState = PviConnectionState.RaySourceConnected;
                    result = true;
                }
                else if (_isVariablesConnected)
                {
                    newState = PviConnectionState.VariablesConnected;
                }
                else if (_isConnected)
                {
                    newState = PviConnectionState.ServiceConnected;
                }
            }

            // 仅在状态变化时触发事件
            if (newState != _currentConnectionState)
            {
                _currentConnectionState = newState;
                ConnectionStateChanged?.Invoke(null, _currentConnectionState);
            }

            return result;
        }

        /// <summary>
        /// 读取错误状态
        /// </summary>
        public static CometErrorData ReadErrors()
        {
            return new CometErrorData
            {
                SystemError = _sysErrR?.Value?.ToString() ?? "",
                HSGError = _HSGErrR?.Value?.ToString() ?? "",
                TubeError = _tubeErrR?.Value?.ToString() ?? "",
                TubeVacError = _tubeACErrR?.Value?.ToString() ?? ""
            };
        }

        #endregion

        #region Disconnect 和 Dispose 资源释放

        /// <summary>
        /// 断开所有 PVI 变量并释放资源
        /// </summary>
        public static void Disconnect()
        {
            Log(CometLogLevel.Info, "执行 Disconnect 操作，断开所有 PVI 变量");

            try
            {
                // 如果射线仍处于开启状态，先关闭高压再断开连接
                if (_isXRayOn)
                {
                    Log(CometLogLevel.Warn, "检测到射线仍处于开启状态，先执行 TurnOff 关闭高压");
                    TurnOff();
                }

                Variable[] allVariables = {
                    _varKVS, _varKVR, _varMAS, _varMAR,
                    _varXonS, _varXoffS, _varXonR,
                    _varWarmUpS, _varWarmUpR,
                    _varVaconS, _varVaconR, _varVaconRV,
                    _varStartUpS, _varStartUpR,
                    _varCurrentKVAutoCenter, _varALLKVCenter, _varAutoCenterR,
                    _varFilamentAdjust, _varFilamentAdjustR,
                    _varInterLockR, _varWatchingDog,
                    _varPowerModeR, _varPowerModeS, _varTxiR,
                    _varTxiOpenS, _varTxiCloseS,
                    _sysErrR, _sysErrS,
                    _HSGErrR, _HSGErrS,
                    _tubeErrR, _tubeErrS,
                    _tubeACErrR, _tubeACErrS
                };

                foreach (var variable in allVariables)
                {
                    if (variable != null)
                    {
                        variable.Active = false;
                        variable.Disconnected += new PviEventHandler(Variable_Disconnected);
                        variable.Disconnect();
                    }
                }

                _isConnected = false;
                _isVariablesConnected = false;
                ConnectionStateChanged?.Invoke(null, PviConnectionState.Disconnected);

                Log(CometLogLevel.Info, "Disconnect 操作完成，所有变量已断开");
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Warn, "Disconnect 过程中发生异常：{0}", ex.Message);
                ErrorOccurred?.Invoke(null, $"Disconnect 异常：{ex.Message}");
                _isConnected = false;
                _isVariablesConnected = false;
            }
        }

        /// <summary>
        /// 变量断开回调：释放变量资源
        /// </summary>
        private static void Variable_Disconnected(object sender, PviEventArgs e)
        {
            try
            {
                var variable = sender as Variable;
                variable?.Dispose();
            }
            catch (Exception ex)
            {
                Log(CometLogLevel.Warn, "变量 Dispose 异常：{0}", ex.Message);
            }
        }

        /// <summary>
        /// 释放所有资源
        /// </summary>
        public static void Dispose()
        {
            Disconnect();

            // 释放 CPU
            try { _cpu?.Dispose(); } catch { }

            // 释放 Service
            try { _service?.Dispose(); } catch { }
        }

        #endregion
    }
}
