using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Prism.Events;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Config;
using XP.Common.Logging.Interfaces;

namespace XP.Hardware.Detector.Implementations
{
    /// <summary>
    /// Varex 探测器实现类 | Varex detector implementation class
    /// 通过 XISL API 控制 Varex 探测器硬件
    /// </summary>
    public class VarexDetector : AreaDetectorBase, IVarexDetector
    {
        #region 私有字段 | Private Fields

        // 配置 | Configuration
        private readonly VarexDetectorConfig _config;

        // 日志服务 | Logger service
        private readonly ILoggerService _logger;

        // 内存管理 | Memory Management
        private readonly ArrayPool<ushort> _arrayPool;
        private readonly ConcurrentQueue<short[]> _imageQueue;

        // XISL 句柄 | XISL Handles
        private IntPtr _hAcqDesc = IntPtr.Zero;
        private IntPtr _pAcqBuffer = IntPtr.Zero;
        private IntPtr _pOffsetBuffer = IntPtr.Zero;
        private IntPtr _pGainBuffer = IntPtr.Zero;
        private IntPtr _pGainAvgBuffer = IntPtr.Zero;  // 增益映射输出缓冲区（DWORD*）| Gain map output buffer (DWORD*)
        private IntPtr _pCorrList = IntPtr.Zero;

        // 回调委托 | Callback Delegates
        private XISLApi.EndFrameCallback _endFrameCallback;
        private XISLApi.EndAcqCallback _endAcqCallback;

        // 事件句柄 | Event Handles
        private IntPtr _hevEndFrame = IntPtr.Zero;
        private IntPtr _hevEndAcq = IntPtr.Zero;

        // 配置参数 | Configuration Parameters
        private BinningMode _binningMode;
        private GainMode _gainMode;
        private uint _exposureTime;
        private (uint x, uint y, uint width, uint height) _roi;

        // 采集控制 | Acquisition Control
        private bool _isAcquiring = false;
        private CancellationTokenSource _acquisitionCts;
        private readonly object _acquisitionLock = new object();

        // 缓存的图像分辨率（初始化/参数变更时更新）| Cached image resolution (updated on init/param change)
        private uint _cachedRows;
        private uint _cachedColumns;

        #endregion

        #region 属性 | Properties

        /// <summary>
        /// 探测器类型 | Detector type
        /// </summary>
        public override DetectorType Type => DetectorType.Varex;

        #endregion

        #region 构造函数 | Constructor

        /// <summary>
        /// 构造函数 | Constructor
        /// </summary>
        /// <param name="config">Varex 探测器配置 | Varex detector configuration</param>
        /// <param name="eventAggregator">事件聚合器 | Event aggregator</param>
        /// <param name="logger">日志服务 | Logger service</param>
        public VarexDetector(VarexDetectorConfig config, IEventAggregator eventAggregator, ILoggerService logger = null)
            : base(eventAggregator)
        {
            _config = config ?? throw new ArgumentNullException(nameof(config));
            _logger = logger?.ForModule("VarexDetector");

            // 初始化内存管理 | Initialize memory management
            _arrayPool = ArrayPool<ushort>.Shared;
            _imageQueue = new ConcurrentQueue<short[]>();

            // 初始化配置参数 | Initialize configuration parameters
            _binningMode = config.BinningMode;
            _gainMode = config.GainMode;
            _exposureTime = config.ExposureTime;
            _roi = (config.RoiX, config.RoiY, config.RoiWidth, config.RoiHeight);

            // 创建回调委托实例（防止被 GC 回收）| Create callback delegate instances (prevent GC collection)
            _endFrameCallback = OnEndFrameCallback;
            _endAcqCallback = OnEndAcqCallback;

            _logger?.Info("VarexDetector 实例已创建 | VarexDetector instance created");
        }

        #endregion

        #region 抽象方法实现（占位符）| Abstract Method Implementations (Placeholders)

        /// <summary>
        /// 初始化探测器内部实现 | Initialize detector internal implementation
        /// </summary>
        protected override Task<DetectorResult> InitializeInternalAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    _logger?.Info("开始初始化 Varex 探测器 | Starting Varex detector initialization");

                    // 1. 调用 VarexDetDll 底层初始化 | Call VarexDetDll low-level initialization
                    _logger?.Debug("调用 DoDetInit 进行底层初始化 | Calling DoDetInit for low-level initialization");
                    int initResult = XISLApi.DoDetInit(ref _hAcqDesc);
                    if (initResult != 0)
                    {
                        var errorMsg = $"探测器底层初始化失败 | Detector low-level initialization failed, DoDetInit 返回码：{initResult}";
                        _logger?.Error(null, errorMsg);
                        return DetectorResult.Failure(errorMsg, null, initResult);
                    }
                    _logger?.Info("DoDetInit 初始化成功 | DoDetInit initialization successful");

                    // 2. 获取探测器句柄 | Get detector handle
                    IntPtr hWnd = IntPtr.Zero;
                    var result = XISLApi.Acquisition_GetNextSensor(ref hWnd, ref _hAcqDesc);
                    if (_hAcqDesc == IntPtr.Zero)
                    {
                        var errorMsg = "获取探测器句柄失败，句柄为空 | Failed to get detector handle, handle is null";
                        _logger?.Error(null, errorMsg);
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }
                    _logger?.Debug("探测器句柄获取成功 | Detector handle acquired successfully");

                    // 3. 注册回调函数 | Register callbacks
                    Thread.Sleep(200);
                    result = XISLApi.Acquisition_SetCallbacksAndMessages(
                        _hAcqDesc, IntPtr.Zero, 0, 0, _endFrameCallback, _endAcqCallback);
                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"注册回调函数失败 | Failed to register callbacks: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }
                    _logger?.Debug("回调函数注册成功 | Callbacks registered successfully");

                    // 4. 设置帧同步模式为内部定时器 | Set frame sync mode to internal timer
                    result = XISLApi.Acquisition_SetFrameSyncMode(_hAcqDesc, (uint)XISLApi.HIS_SYNCMODE_INTERNAL_TIMER);
                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        _logger?.Warn($"设置帧同步模式失败 | Failed to set frame sync mode: {result}");
                    }

                    // 5. 获取探测器配置（分辨率等）| Get detector configuration (resolution etc.)
                    uint dwFrames, dwRows, dwColumns, dwDataType, dwSortFlags;
                    uint dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
                    int iIRQFlags;
                    result = XISLApi.Acquisition_GetConfiguration(
                        _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                        out dwDataType, out dwSortFlags, out iIRQFlags,
                        out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);
                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"获取探测器配置失败 | Failed to get detector configuration: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }
                    _logger?.Info($"探测器配置：分辨率 {dwColumns}x{dwRows}，数据类型 {dwDataType} | Detector config: resolution {dwColumns}x{dwRows}, data type {dwDataType}");

                    // 6. 分配采集缓冲区（校正缓冲区保持 IntPtr.Zero，未校正前不可传给 API）
                    // Allocate acquisition buffer (correction buffers stay IntPtr.Zero until calibration is done)
                    int bufferSize = (int)(dwRows * dwColumns * sizeof(ushort));
                    _pAcqBuffer = Marshal.AllocHGlobal(bufferSize);
                    _logger?.Debug($"采集缓冲区已分配，大小：{bufferSize} 字节 | Acquisition buffer allocated, size: {bufferSize} bytes");

                    // 7. 定义目标缓冲区 | Define destination buffers
                    result = XISLApi.Acquisition_DefineDestBuffers(
                        _hAcqDesc, _pAcqBuffer, 1, dwRows, dwColumns);
                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"定义目标缓冲区失败 | Failed to define destination buffers: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }
                    _logger?.Debug("目标缓冲区定义成功 | Destination buffers defined successfully");

                    // 9. 创建事件句柄 | Create event handles
                    _hevEndFrame = XISLApi.CreateEvent(IntPtr.Zero, false, false, null);
                    _hevEndAcq = XISLApi.CreateEvent(IntPtr.Zero, false, false, null);
                    _logger?.Debug("事件句柄已创建 | Event handles created");

                    // 10. 应用初始配置（Binning/增益/曝光时间）| Apply initial configuration (Binning/Gain/Exposure)
                    var configResult = ApplyConfiguration();
                    if (!configResult.IsSuccess)
                    {
                        _logger?.Error(null, $"应用初始配置失败 | Failed to apply initial configuration: {configResult.ErrorMessage}");
                        return configResult;
                    }

                    _logger?.Info("Varex 探测器初始化成功 | Varex detector initialized successfully");
                    return DetectorResult.Success("Varex 探测器初始化成功 | Varex detector initialized successfully");
                }
                catch (Exception ex)
                {
                    var errorMsg = $"初始化异常 | Initialization exception: {ex.Message}";
                    _logger?.Error(ex, errorMsg);
                    return DetectorResult.Failure(errorMsg, ex, -1);
                }
            }, cancellationToken);
        }


        /// <summary>
        /// 应用配置参数 | Apply configuration parameters
        /// </summary>
        private DetectorResult ApplyConfiguration()
        {
            try
            {
                // 设置 Binning 模式（API 值从 1 开始）| Set binning mode (API value starts from 1)
                var result = XISLApi.Acquisition_SetCameraBinningMode(_hAcqDesc, (uint)_binningMode + 1);
                if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                {
                    return DetectorResult.Failure($"设置 Binning 模式失败 | Failed to set binning mode: {result}");
                }

                // 设置增益模式 | Set gain mode
                result = XISLApi.Acquisition_SetCameraGain(_hAcqDesc, (uint)_gainMode);
                if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                {
                    return DetectorResult.Failure($"设置增益模式失败 | Failed to set gain mode: {result}");
                }

                // 设置曝光时间 | Set exposure time
                uint exposureTime = _exposureTime;
                result = XISLApi.Acquisition_SetTimerSync(_hAcqDesc, ref exposureTime);
                if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                {
                    return DetectorResult.Failure($"设置曝光时间失败 | Failed to set exposure time: {result}");
                }

                return DetectorResult.Success("配置应用成功 | Configuration applied successfully");
            }
            catch (Exception ex)
            {
                return DetectorResult.Failure($"应用配置异常 | Apply configuration exception: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取当前帧号 | Get current frame number
        /// </summary>
        private int GetCurrentFrameNumber()
        {
            uint dwActFrame, dwSecFrame;
            XISLApi.Acquisition_GetActFrame(_hAcqDesc, out dwActFrame, out dwSecFrame);
            return (int)dwActFrame;
        }


        /// <summary>
        /// 启动连续采集内部实现 | Start continuous acquisition internal implementation
        /// </summary>
        /// <summary>
        /// 采集前准备：获取配置、分配缓冲区、定义目标缓冲区、设置采集标志
        /// Prepare for acquisition: get config, allocate buffers, define dest buffers, set acq data
        /// </summary>
        private DetectorResult PrepareForAcquisition(uint acqDataFlag, int targetFrames, out uint dwRows, out uint dwColumns)
        {
            dwRows = 0;
            dwColumns = 0;

            // 1. 获取当前探测器配置（Binning 改变后分辨率会变）| Get current config (resolution changes with binning)
            uint dwFrames, dwDataType, dwSortFlags, dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
            int iIRQFlags;
            var result = XISLApi.Acquisition_GetConfiguration(
                _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                out dwDataType, out dwSortFlags, out iIRQFlags,
                out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);
            if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
            {
                return DetectorResult.Failure($"获取探测器配置失败 | Failed to get detector configuration: {result}", null, (int)result);
            }
            _logger?.Debug($"采集前配置：分辨率 {dwColumns}x{dwRows} | Pre-acquisition config: resolution {dwColumns}x{dwRows}");

            // 缓存分辨率供回调使用 | Cache resolution for callback use
            _cachedRows = dwRows;
            _cachedColumns = dwColumns;

            // 2. 设置采集数据标志 | Set acquisition data flag
            uint acqData = acqDataFlag;
            result = XISLApi.Acquisition_SetAcqData(_hAcqDesc, ref acqData);
            if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
            {
                return DetectorResult.Failure($"设置采集数据标志失败 | Failed to set acquisition data flag: {result}", null, (int)result);
            }

            // 3. 重新分配采集缓冲区 | Reallocate acquisition buffer
            if (_pAcqBuffer != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(_pAcqBuffer);
            }
            _pAcqBuffer = Marshal.AllocHGlobal(targetFrames * (int)dwRows * (int)dwColumns * sizeof(ushort));

            // 4. 定义目标缓冲区 | Define destination buffers
            result = XISLApi.Acquisition_DefineDestBuffers(_hAcqDesc, _pAcqBuffer, targetFrames, dwRows, dwColumns);
            if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
            {
                return DetectorResult.Failure($"定义目标缓冲区失败 | Failed to define destination buffers: {result}", null, (int)result);
            }

            return DetectorResult.Success();
        }

        protected override Task<DetectorResult> StartAcquisitionInternalAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    _logger?.Info("开始启动连续采集 | Starting continuous acquisition");

                    // 检查取消令牌 | Check cancellation token
                    if (cancellationToken.IsCancellationRequested)
                    {
                        _logger?.Warn("启动采集操作已取消 | Start acquisition operation cancelled");
                        return DetectorResult.Failure("操作已取消 | Operation cancelled");
                    }

                    lock (_acquisitionLock)
                    {
                        // 防止重复启动 | Prevent duplicate start
                        if (_isAcquiring)
                        {
                            var errorMsg = "采集已在进行中，无法重复启动 | Acquisition already in progress, cannot start again";
                            _logger?.Warn(errorMsg);
                            return DetectorResult.Failure(errorMsg);
                        }

                        // 确保之前的 CancellationTokenSource 已清理 | Ensure previous CancellationTokenSource is cleaned up
                        if (_acquisitionCts != null)
                        {
                            _logger?.Debug("清理之前的 CancellationTokenSource | Cleaning up previous CancellationTokenSource");
                            try
                            {
                                _acquisitionCts.Cancel();
                                _acquisitionCts.Dispose();
                            }
                            catch (Exception ex)
                            {
                                _logger?.Warn($"清理 CancellationTokenSource 时发生异常 | Exception while cleaning CancellationTokenSource: {ex.Message}");
                            }
                            _acquisitionCts = null;
                        }

                        _isAcquiring = true;
                        _acquisitionCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                    }

                    // 再次检查取消令牌 | Check cancellation token again
                    if (cancellationToken.IsCancellationRequested)
                    {
                        lock (_acquisitionLock)
                        {
                            _isAcquiring = false;
                            _acquisitionCts?.Dispose();
                            _acquisitionCts = null;
                        }
                        _logger?.Warn("启动采集操作已取消 | Start acquisition operation cancelled");
                        return DetectorResult.Failure("操作已取消 | Operation cancelled");
                    }

                    // 启动连续采集前准备 | Prepare before starting continuous acquisition
                    var prepResult = PrepareForAcquisition(XISLApi.ACQ_SNAP, 1, out uint dwRows, out uint dwColumns);
                    if (!prepResult.IsSuccess)
                    {
                        lock (_acquisitionLock)
                        {
                            _isAcquiring = false;
                            _acquisitionCts?.Dispose();
                            _acquisitionCts = null;
                        }
                        _logger?.Error(null, $"采集准备失败 | Acquisition preparation failed: {prepResult.ErrorMessage}");
                        return prepResult;
                    }

                    // 启动连续采集 | Start continuous acquisition
                    var result = XISLApi.Acquisition_Acquire_Image(
                        _hAcqDesc,
                        1, // 帧数 | Frame count
                        0, // 跳过帧数 | Skip frames
                        (uint)XISLApi.HIS_SEQ_CONTINUOUS,
                        _pOffsetBuffer,  // 未校正时为 IntPtr.Zero | IntPtr.Zero before calibration
                        _pGainAvgBuffer, // 未校正时为 IntPtr.Zero，校正后为增益映射 | IntPtr.Zero before calibration, gain map after
                        _pCorrList);     // 未校正时为 IntPtr.Zero | IntPtr.Zero before calibration

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        lock (_acquisitionLock)
                        {
                            _isAcquiring = false;
                            _acquisitionCts?.Dispose();
                            _acquisitionCts = null;
                        }
                        var errorMsg = $"启动采集失败 | Failed to start acquisition: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    _logger?.Info("连续采集已启动 | Continuous acquisition started");
                    return DetectorResult.Success("采集已启动 | Acquisition started");
                }
                catch (OperationCanceledException)
                {
                    lock (_acquisitionLock)
                    {
                        _isAcquiring = false;
                        _acquisitionCts?.Dispose();
                        _acquisitionCts = null;
                    }
                    _logger?.Warn("启动采集操作已取消 | Start acquisition operation cancelled");
                    return DetectorResult.Failure("操作已取消 | Operation cancelled");
                }
                catch (Exception ex)
                {
                    lock (_acquisitionLock)
                    {
                        _isAcquiring = false;
                        _acquisitionCts?.Dispose();
                        _acquisitionCts = null;
                    }
                    var errorMsg = $"启动采集异常 | Start acquisition exception: {ex.Message}";
                    _logger?.Error(ex, errorMsg);
                    return DetectorResult.Failure(errorMsg, ex, -1);
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 停止采集内部实现 | Stop acquisition internal implementation
        /// </summary>
        protected override Task<DetectorResult> StopAcquisitionInternalAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    _logger?.Info("开始停止采集 | Starting to stop acquisition");

                    // 检查取消令牌 | Check cancellation token
                    if (cancellationToken.IsCancellationRequested)
                    {
                        _logger?.Warn("停止采集操作已取消 | Stop acquisition operation cancelled");
                        return DetectorResult.Failure("操作已取消 | Operation cancelled");
                    }

                    lock (_acquisitionLock)
                    {
                        // 幂等性检查：如果未在采集，直接返回成功 | Idempotency check: if not acquiring, return success
                        if (!_isAcquiring)
                        {
                            _logger?.Debug("采集未运行，无需停止 | Acquisition not running, no need to stop");
                            return DetectorResult.Success("采集未运行 | Acquisition not running");
                        }
                    }

                    // 停止采集 | Stop acquisition
                    var result = XISLApi.Acquisition_Abort(_hAcqDesc);
                    _logger?.Debug($"调用 Acquisition_Abort，返回码：{result} | Called Acquisition_Abort, return code: {result}");

                    // 等待采集结束事件，支持取消令牌 | Wait for acquisition end event, support cancellation token
                    const int timeoutMs = 5000; // 5 秒超时 | 5 seconds timeout
                    const int pollIntervalMs = 100; // 轮询间隔 | Poll interval
                    int elapsedMs = 0;

                    while (elapsedMs < timeoutMs)
                    {
                        // 检查取消令牌 | Check cancellation token
                        if (cancellationToken.IsCancellationRequested)
                        {
                            _logger?.Warn("停止采集操作已取消，但仍会清理资源 | Stop acquisition operation cancelled, but will still clean up resources");
                            break;
                        }

                        uint waitResult = XISLApi.WaitForSingleObject(_hevEndAcq, (uint)pollIntervalMs);
                        
                        if (waitResult == XISLApi.WAIT_OBJECT_0)
                        {
                            // 成功等到事件 | Successfully waited for event
                            break;
                        }

                        elapsedMs += pollIntervalMs;
                    }

                    // 清理资源 | Clean up resources
                    lock (_acquisitionLock)
                    {
                        _isAcquiring = false;
                        
                        if (_acquisitionCts != null)
                        {
                            try
                            {
                                _acquisitionCts.Cancel();
                                _acquisitionCts.Dispose();
                            }
                            catch (Exception ex)
                            {
                                _logger?.Warn($"清理 CancellationTokenSource 时发生异常 | Exception while cleaning CancellationTokenSource: {ex.Message}");
                            }
                            _acquisitionCts = null;
                        }
                    }

                    // 检查是否超时 | Check if timeout occurred
                    if (elapsedMs >= timeoutMs && !cancellationToken.IsCancellationRequested)
                    {
                        var errorMsg = $"停止采集超时（{timeoutMs}ms），但资源已清理 | Stop acquisition timeout ({timeoutMs}ms), but resources cleaned up";
                        _logger?.Warn(errorMsg);
                        return DetectorResult.Failure(errorMsg, null, -2);
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        _logger?.Info("停止采集操作已取消，资源已清理 | Stop acquisition operation cancelled, resources cleaned up");
                        return DetectorResult.Failure("操作已取消 | Operation cancelled");
                    }

                    // 等待硬件完全释放采集资源，避免后续操作出现 HIS_ERROR_TIMEOUT
                    // Wait for hardware to fully release acquisition resources to avoid HIS_ERROR_TIMEOUT on subsequent operations
                    Thread.Sleep(200);

                    _logger?.Info("采集已停止 | Acquisition stopped");
                    return DetectorResult.Success("采集已停止 | Acquisition stopped");
                }
                catch (OperationCanceledException)
                {
                    // 确保资源清理 | Ensure resource cleanup
                    lock (_acquisitionLock)
                    {
                        _isAcquiring = false;
                        _acquisitionCts?.Dispose();
                        _acquisitionCts = null;
                    }
                    _logger?.Warn("停止采集操作已取消 | Stop acquisition operation cancelled");
                    return DetectorResult.Failure("操作已取消 | Operation cancelled");
                }
                catch (Exception ex)
                {
                    // 确保资源清理 | Ensure resource cleanup
                    lock (_acquisitionLock)
                    {
                        _isAcquiring = false;
                        _acquisitionCts?.Dispose();
                        _acquisitionCts = null;
                    }
                    var errorMsg = $"停止采集异常 | Stop acquisition exception: {ex.Message}";
                    _logger?.Error(ex, errorMsg);
                    return DetectorResult.Failure(errorMsg, ex, -1);
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 单帧采集内部实现 | Single frame acquisition internal implementation
        /// </summary>
        protected override Task<DetectorResult> AcquireSingleFrameInternalAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    // 单帧采集前准备（含重试机制，防止连续采集停止后硬件未完全释放）
                    // Prepare before single frame acquisition (with retry to handle hardware not fully released after continuous acquisition)
                    DetectorResult prepResult = null;
                    const int maxRetries = 3;
                    const int retryDelayMs = 300;

                    for (int attempt = 1; attempt <= maxRetries; attempt++)
                    {
                        prepResult = PrepareForAcquisition(XISLApi.ACQ_SNAP, 1, out uint dwRows, out uint dwColumns);
                        if (prepResult.IsSuccess)
                        {
                            // 采集单帧 | Acquire single frame
                            var result = XISLApi.Acquisition_Acquire_Image(
                                _hAcqDesc,
                                1, // 采集 1 帧 | Acquire 1 frame
                                0, // 跳过帧数 | Skip frames
                                (uint)XISLApi.HIS_SEQ_ONE_BUFFER,
                                _pOffsetBuffer,
                                _pGainAvgBuffer,
                                _pCorrList);

                            if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                            {
                                return DetectorResult.Failure($"单帧采集失败 | Failed to acquire single frame: {result}");
                            }

                            // 等待帧结束事件 | Wait for frame end event
                            uint waitResult = XISLApi.WaitForSingleObject(_hevEndFrame, 5000);

                            if (waitResult != XISLApi.WAIT_OBJECT_0)
                            {
                                return DetectorResult.Failure("单帧采集超时 | Single frame acquisition timeout");
                            }

                            return DetectorResult.Success("单帧采集成功 | Single frame acquired successfully");
                        }

                        // 准备失败，等待后重试 | Preparation failed, wait and retry
                        if (attempt < maxRetries)
                        {
                            _logger?.Warn($"单帧采集准备失败（第 {attempt} 次），{retryDelayMs}ms 后重试 | " +
                                          $"Single frame preparation failed (attempt {attempt}), retrying in {retryDelayMs}ms: {prepResult.ErrorMessage}");
                            Thread.Sleep(retryDelayMs);
                        }
                    }

                    // 所有重试均失败 | All retries failed
                    _logger?.Error(null, $"单帧采集准备失败（已重试 {maxRetries} 次）| Single frame preparation failed after {maxRetries} retries: {prepResult?.ErrorMessage}");
                    return prepResult ?? DetectorResult.Failure("单帧采集准备失败 | Single frame preparation failed");
                }
                catch (Exception ex)
                {
                    return DetectorResult.Failure($"单帧采集异常 | Single frame acquisition exception: {ex.Message}", ex);
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 暗场校正内部实现 | Dark correction internal implementation
        /// </summary>
        protected override Task<DetectorResult> DarkCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    _logger?.Info($"开始暗场校正，帧数：{frameCount} | Starting dark correction, frame count: {frameCount}");

                    // 1. 获取探测器配置信息 | Get detector configuration
                    uint dwFrames, dwRows, dwColumns, dwDataType, dwSortFlags;
                    uint dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
                    int iIRQFlags;
                    var result = XISLApi.Acquisition_GetConfiguration(
                        _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                        out dwDataType, out dwSortFlags, out iIRQFlags,
                        out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"获取探测器配置失败 | Failed to get detector configuration: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    // 2. 分配暗场缓冲区（如果尚未分配或大小不匹配）| Allocate offset buffer if not allocated or size mismatch
                    int requiredSize = (int)(dwRows * dwColumns) * sizeof(ushort);
                    if (_pOffsetBuffer == IntPtr.Zero)
                    {
                        _pOffsetBuffer = Marshal.AllocHGlobal(requiredSize);
                        _logger?.Debug($"已分配暗场缓冲区，大小：{requiredSize} 字节 | Allocated offset buffer, size: {requiredSize} bytes");
                    }

                    // 3. 调用 XISL API 采集暗场图像 | Call XISL API to acquire offset image
                    _logger?.Debug($"调用 Acquisition_Acquire_OffsetImage，分辨率：{dwColumns}x{dwRows} | Calling Acquisition_Acquire_OffsetImage, resolution: {dwColumns}x{dwRows}");
                    result = XISLApi.Acquisition_Acquire_OffsetImage(
                        _hAcqDesc, _pOffsetBuffer, dwRows, dwColumns, (uint)frameCount);

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"采集暗场图像失败 | Failed to acquire offset image: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    // 3. 等待采集完成 | Wait for acquisition to complete
                    uint waitResult = XISLApi.WaitForSingleObject(_hevEndAcq, 60000); // 60 秒超时
                    if (waitResult != XISLApi.WAIT_OBJECT_0)
                    {
                        var errorMsg = $"等待暗场采集完成超时 | Timeout waiting for offset acquisition: {waitResult}";
                        _logger?.Warn(errorMsg);
                        return DetectorResult.Failure(errorMsg, null, (int)waitResult);
                    }

                    // 4. 保存暗场数据到配置的存储路径 | Save offset data to configured storage path
                    if (_config.AutoSave && !string.IsNullOrEmpty(_config.SavePath))
                    {
                        try
                        {
                            string offsetFilePath = System.IO.Path.Combine(_config.SavePath, $"offset_{DateTime.Now:yyyyMMdd_HHmmss}.raw");
                            System.IO.Directory.CreateDirectory(_config.SavePath);
                            
                            int bufferSize = (int)(dwRows * dwColumns * sizeof(ushort));
                            byte[] offsetData = new byte[bufferSize];
                            Marshal.Copy(_pOffsetBuffer, offsetData, 0, bufferSize);
                            System.IO.File.WriteAllBytes(offsetFilePath, offsetData);
                            _logger?.Info($"暗场数据已保存到：{offsetFilePath} | Offset data saved to: {offsetFilePath}");
                        }
                        catch (Exception ex)
                        {
                            // 保存失败不影响校正结果，仅记录错误 | Save failure doesn't affect correction result, just log error
                            var errorMsg = $"保存暗场数据失败 | Failed to save offset data: {ex.Message}";
                            _logger?.Warn(errorMsg);
                            PublishError(DetectorResult.Failure(errorMsg, ex));
                        }
                    }

                    // 5. 发布校正完成事件 | Publish correction completed event
                    var correctionResult = DetectorResult.Success("暗场校正完成 | Dark correction completed");
                    PublishCorrectionCompleted(CorrectionType.Dark, correctionResult);
                    _logger?.Info("暗场校正完成 | Dark correction completed");

                    return correctionResult;
                }
                catch (Exception ex)
                {
                    var errorMsg = $"暗场校正异常 | Dark correction exception: {ex.Message}";
                    _logger?.Error(ex, errorMsg);
                    var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                    PublishError(errorResult);
                    return errorResult;
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 增益校正内部实现 | Gain correction internal implementation
        /// </summary>
        protected override Task<DetectorResult> GainCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    _logger?.Info($"开始增益校正，帧数：{frameCount} | Starting gain correction, frame count: {frameCount}");

                    // 1. 获取探测器配置信息 | Get detector configuration
                    uint dwFrames, dwRows, dwColumns, dwDataType, dwSortFlags;
                    uint dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
                    int iIRQFlags;
                    var result = XISLApi.Acquisition_GetConfiguration(
                        _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                        out dwDataType, out dwSortFlags, out iIRQFlags,
                        out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"获取探测器配置失败 | Failed to get detector configuration: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    // 2. 分配增益采集缓冲区（ushort，用于 Acquire_GainImage 输入）| Allocate gain acquisition buffer (ushort, for Acquire_GainImage)
                    int gainAcqSize = (int)(dwRows * dwColumns) * sizeof(ushort);
                    if (_pGainBuffer == IntPtr.Zero)
                    {
                        _pGainBuffer = Marshal.AllocHGlobal(gainAcqSize);
                        _logger?.Debug($"已分配增益采集缓冲区，大小：{gainAcqSize} 字节 | Allocated gain acquisition buffer, size: {gainAcqSize} bytes");
                    }

                    // 分配增益映射输出缓冲区（uint/DWORD，用于 CreateGainMap 输出）| Allocate gain map output buffer (uint/DWORD, for CreateGainMap)
                    int gainAvgSize = (int)(dwRows * dwColumns) * sizeof(uint);
                    if (_pGainAvgBuffer == IntPtr.Zero)
                    {
                        _pGainAvgBuffer = Marshal.AllocHGlobal(gainAvgSize);
                        _logger?.Debug($"已分配增益映射缓冲区，大小：{gainAvgSize} 字节 | Allocated gain map buffer, size: {gainAvgSize} bytes");
                    }

                    // 3. 调用 XISL API 采集增益图像 | Call XISL API to acquire gain image
                    _logger?.Debug($"调用 Acquisition_Acquire_GainImage，分辨率：{dwColumns}x{dwRows} | Calling Acquisition_Acquire_GainImage, resolution: {dwColumns}x{dwRows}");
                    result = XISLApi.Acquisition_Acquire_GainImage(
                        _hAcqDesc, _pOffsetBuffer, _pGainBuffer, dwRows, dwColumns, (uint)frameCount);

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"采集增益图像失败 | Failed to acquire gain image: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    // 3. 等待采集完成 | Wait for acquisition to complete
                    uint waitResult = XISLApi.WaitForSingleObject(_hevEndAcq, 60000); // 60 秒超时
                    if (waitResult != XISLApi.WAIT_OBJECT_0)
                    {
                        var errorMsg = $"等待增益采集完成超时 | Timeout waiting for gain acquisition: {waitResult}";
                        _logger?.Warn(errorMsg);
                        return DetectorResult.Failure(errorMsg, null, (int)waitResult);
                    }

                    // 4. 创建增益映射（输入为采集的 ushort 数据，输出为 DWORD 映射）| Create gain map (input: ushort data, output: DWORD map)
                    _logger?.Debug("创建增益映射 | Creating gain map");
                    result = XISLApi.Acquisition_CreateGainMap(_pGainBuffer, _pGainAvgBuffer, (int)(dwRows * dwColumns), frameCount);
                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        var errorMsg = $"创建增益映射失败 | Failed to create gain map: {result}";
                        _logger?.Error(null, errorMsg + $"，返回码：{(int)result}");
                        return DetectorResult.Failure(errorMsg, null, (int)result);
                    }

                    // 5. 保存增益数据到配置的存储路径 | Save gain data to configured storage path
                    if (_config.AutoSave && !string.IsNullOrEmpty(_config.SavePath))
                    {
                        try
                        {
                            string gainFilePath = System.IO.Path.Combine(_config.SavePath, $"gain_{DateTime.Now:yyyyMMdd_HHmmss}.raw");
                            System.IO.Directory.CreateDirectory(_config.SavePath);
                            
                            int bufferSize = (int)(dwRows * dwColumns * sizeof(uint));
                            byte[] gainData = new byte[bufferSize];
                            Marshal.Copy(_pGainAvgBuffer, gainData, 0, bufferSize);
                            System.IO.File.WriteAllBytes(gainFilePath, gainData);
                            _logger?.Info($"增益数据已保存到：{gainFilePath} | Gain data saved to: {gainFilePath}");
                        }
                        catch (Exception ex)
                        {
                            // 保存失败不影响校正结果，仅记录错误 | Save failure doesn't affect correction result, just log error
                            var errorMsg = $"保存增益数据失败 | Failed to save gain data: {ex.Message}";
                            _logger?.Warn(errorMsg);
                            PublishError(DetectorResult.Failure(errorMsg, ex));
                        }
                    }

                    // 6. 发布校正完成事件 | Publish correction completed event
                    var correctionResult = DetectorResult.Success("增益校正完成 | Gain correction completed");
                    PublishCorrectionCompleted(CorrectionType.Gain, correctionResult);
                    _logger?.Info("增益校正完成 | Gain correction completed");

                    return correctionResult;
                }
                catch (Exception ex)
                {
                    var errorMsg = $"增益校正异常 | Gain correction exception: {ex.Message}";
                    _logger?.Error(ex, errorMsg);
                    var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                    PublishError(errorResult);
                    return errorResult;
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 自动校正内部实现 | Auto correction internal implementation
        /// </summary>
        protected override async Task<DetectorResult> AutoCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken)
        {
            try
            {
                _logger?.Info($"开始自动校正，帧数：{frameCount} | Starting auto correction, frame count: {frameCount}");

                // 1. 执行暗场校正 | Execute dark correction
                _logger?.Debug("执行暗场校正 | Executing dark correction");
                var darkResult = await DarkCorrectionInternalAsync(frameCount, cancellationToken);
                if (!darkResult.IsSuccess)
                {
                    var errorMsg = $"自动校正失败：暗场校正失败 | Auto correction failed: dark correction failed - {darkResult.ErrorMessage}";
                    _logger?.Error(null, errorMsg);
                    return DetectorResult.Failure(errorMsg, darkResult.Exception, darkResult.ErrorCode);
                }

                // 2. 执行增益校正 | Execute gain correction
                _logger?.Debug("执行增益校正 | Executing gain correction");
                var gainResult = await GainCorrectionInternalAsync(frameCount, cancellationToken);
                if (!gainResult.IsSuccess)
                {
                    var errorMsg = $"自动校正失败：增益校正失败 | Auto correction failed: gain correction failed - {gainResult.ErrorMessage}";
                    _logger?.Error(null, errorMsg);
                    return DetectorResult.Failure(errorMsg, gainResult.Exception, gainResult.ErrorCode);
                }

                // 3. 执行坏像素校正 | Execute bad pixel correction
                _logger?.Debug("执行坏像素校正 | Executing bad pixel correction");
                var badPixelResult = await BadPixelCorrectionInternalAsync(cancellationToken);
                if (!badPixelResult.IsSuccess)
                {
                    var errorMsg = $"自动校正失败：坏像素校正失败 | Auto correction failed: bad pixel correction failed - {badPixelResult.ErrorMessage}";
                    _logger?.Error(null, errorMsg);
                    return DetectorResult.Failure(errorMsg, badPixelResult.Exception, badPixelResult.ErrorCode);
                }

                // 4. 发布自动校正完成事件 | Publish auto correction completed event
                var correctionResult = DetectorResult.Success("自动校正完成 | Auto correction completed");
                PublishCorrectionCompleted(CorrectionType.Auto, correctionResult);
                _logger?.Info("自动校正完成 | Auto correction completed");

                return correctionResult;
            }
            catch (Exception ex)
            {
                var errorMsg = $"自动校正异常 | Auto correction exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                PublishError(errorResult);
                return errorResult;
            }
        }

        /// <summary>
        /// 坏像素校正内部实现 | Bad pixel correction internal implementation
        /// </summary>
        protected override Task<DetectorResult> BadPixelCorrectionInternalAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                try
                {
                    // 1. 获取探测器配置信息 | Get detector configuration
                    uint dwFrames, dwRows, dwColumns, dwDataType, dwSortFlags;
                    uint dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
                    int iIRQFlags;
                    var result = XISLApi.Acquisition_GetConfiguration(
                        _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                        out dwDataType, out dwSortFlags, out iIRQFlags,
                        out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);

                    if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        return DetectorResult.Failure($"获取探测器配置失败 | Failed to get detector configuration: {result}");
                    }

                    // 2. 分配坏像素映射数据缓冲区 | Allocate bad pixel map data buffer
                    int pixelMapSize = (int)(dwRows * dwColumns);
                    IntPtr pPixelMapData = Marshal.AllocHGlobal(pixelMapSize * sizeof(ushort));

                    try
                    {
                        // 3. 第一次调用获取列表大小 | First call to get list size
                        int corrListSize = 0;
                        result = XISLApi.Acquisition_CreatePixelMap(
                            pPixelMapData, (int)dwRows, (int)dwColumns, IntPtr.Zero, ref corrListSize);

                        if (result != XISLApi.HIS_RETURN.HIS_ALL_OK && corrListSize == 0)
                        {
                            Marshal.FreeHGlobal(pPixelMapData);
                            return DetectorResult.Failure($"获取坏像素列表大小失败 | Failed to get bad pixel list size: {result}");
                        }

                        // 4. 分配坏像素校正列表缓冲区 | Allocate bad pixel correction list buffer
                        if (_pCorrList != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(_pCorrList);
                        }
                        _pCorrList = Marshal.AllocHGlobal(corrListSize);
                        _logger?.Debug($"已分配坏像素校正列表缓冲区，大小：{corrListSize} 字节 | Allocated bad pixel correction list buffer, size: {corrListSize} bytes");

                        // 5. 第二次调用创建坏像素列表 | Second call to create bad pixel list
                        result = XISLApi.Acquisition_CreatePixelMap(
                            pPixelMapData, (int)dwRows, (int)dwColumns, _pCorrList, ref corrListSize);

                        if (result != XISLApi.HIS_RETURN.HIS_ALL_OK)
                        {
                            Marshal.FreeHGlobal(pPixelMapData);
                            return DetectorResult.Failure($"创建坏像素列表失败 | Failed to create bad pixel list: {result}");
                        }

                        // 5. 保存坏像素数据到配置的存储路径 | Save bad pixel data to configured storage path
                        if (_config.AutoSave && !string.IsNullOrEmpty(_config.SavePath))
                        {
                            try
                            {
                                string badPixelFilePath = System.IO.Path.Combine(_config.SavePath, $"badpixel_{DateTime.Now:yyyyMMdd_HHmmss}.raw");
                                System.IO.Directory.CreateDirectory(_config.SavePath);
                                
                                byte[] badPixelData = new byte[corrListSize];
                                Marshal.Copy(_pCorrList, badPixelData, 0, corrListSize);
                                System.IO.File.WriteAllBytes(badPixelFilePath, badPixelData);
                            }
                            catch (Exception ex)
                            {
                                // 保存失败不影响校正结果，仅记录错误 | Save failure doesn't affect correction result, just log error
                                PublishError(DetectorResult.Failure($"保存坏像素数据失败 | Failed to save bad pixel data: {ex.Message}", ex));
                            }
                        }

                        // 6. 发布校正完成事件 | Publish correction completed event
                        var correctionResult = DetectorResult.Success($"坏像素校正完成，检测到 {corrListSize} 个坏像素 | Bad pixel correction completed, detected {corrListSize} bad pixels");
                        PublishCorrectionCompleted(CorrectionType.BadPixel, correctionResult);

                        return correctionResult;
                    }
                    finally
                    {
                        // 释放临时缓冲区 | Release temporary buffer
                        Marshal.FreeHGlobal(pPixelMapData);
                    }
                }
                catch (Exception ex)
                {
                    var errorResult = DetectorResult.Failure($"坏像素校正异常 | Bad pixel correction exception: {ex.Message}", ex);
                    PublishError(errorResult);
                    return errorResult;
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 获取探测器信息 | Get detector information
        /// </summary>
        public override DetectorInfo GetInfo()
        {
            try
            {
                var info = new DetectorInfo
                {
                    Type = DetectorType.Varex,
                    Model = "Varex 4343N", // 默认型号 | Default model
                    SerialNumber = "Unknown", // 序列号需要从硬件查询 | Serial number needs to be queried from hardware
                    FirmwareVersion = "Unknown", // 固件版本需要从硬件查询 | Firmware version needs to be queried from hardware
                    BitDepth = 16 // Varex 探测器使用 16 位数据 | Varex detector uses 16-bit data
                };

                // 如果探测器已初始化，从 XISL API 获取配置信息 | If detector is initialized, get configuration from XISL API
                if (_hAcqDesc != IntPtr.Zero)
                {
                    uint dwFrames, dwRows, dwColumns, dwDataType, dwSortFlags;
                    uint dwAcqType, dwSystemID, dwSyncMode, dwHwAccess;
                    int iIRQFlags;

                    var result = XISLApi.Acquisition_GetConfiguration(
                        _hAcqDesc, out dwFrames, out dwRows, out dwColumns,
                        out dwDataType, out dwSortFlags, out iIRQFlags,
                        out dwAcqType, out dwSystemID, out dwSyncMode, out dwHwAccess);

                    if (result == XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        info.MaxWidth = dwColumns;
                        info.MaxHeight = dwRows;

                        // 根据型号设置像素尺寸 | Set pixel size based on model
                        // Varex 4343N 的像素尺寸为 139 微米 | Varex 4343N pixel size is 139 micrometers
                        info.PixelSize = 139.0;

                        // 根据 SystemID 确定具体型号 | Determine specific model based on SystemID
                        info.Model = dwSystemID switch
                        {
                            _ => "Varex 4343N" // 默认型号 | Default model
                        };
                    }
                    else
                    {
                        // 如果无法获取配置，使用默认值 | If configuration cannot be obtained, use default values
                        info.MaxWidth = 2880;
                        info.MaxHeight = 2880;
                        info.PixelSize = 139.0;
                    }
                }
                else
                {
                    // 探测器未初始化，使用默认值 | Detector not initialized, use default values
                    info.MaxWidth = 2880;
                    info.MaxHeight = 2880;
                    info.PixelSize = 139.0;
                }

                return info;
            }
            catch (Exception ex)
            {
                // 发生异常时返回基本信息 | Return basic information when exception occurs
                return new DetectorInfo
                {
                    Type = DetectorType.Varex,
                    Model = "Varex (Error)",
                    SerialNumber = $"Error: {ex.Message}",
                    FirmwareVersion = "Unknown",
                    MaxWidth = 2880,
                    MaxHeight = 2880,
                    PixelSize = 139.0,
                    BitDepth = 16
                };
            }
        }

        #endregion

        #region IVarexDetector 接口实现（占位符）| IVarexDetector Interface Implementations (Placeholders)

        /// <summary>
        /// 设置 Binning 模式 | Set binning mode
        /// </summary>
        public Task<DetectorResult> SetBinningModeAsync(BinningMode mode)
        {
            return Task.Run(() =>
            {
                try
                {
                    var result = XISLApi.Acquisition_SetCameraBinningMode(_hAcqDesc, (uint)mode + 1);
                    if (result == XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        _binningMode = mode;
                        return DetectorResult.Success($"Binning 模式已设置为 {mode} | Binning mode set to {mode}");
                    }
                    return DetectorResult.Failure($"设置 Binning 模式失败 | Failed to set binning mode: {result}");
                }
                catch (Exception ex)
                {
                    return DetectorResult.Failure($"设置 Binning 模式异常 | Set binning mode exception: {ex.Message}", ex);
                }
            });
        }

        /// <summary>
        /// 获取 Binning 模式 | Get binning mode
        /// </summary>
        public BinningMode GetBinningMode()
        {
            return _binningMode;
        }

        /// <summary>
        /// 设置增益模式 | Set gain mode
        /// </summary>
        public Task<DetectorResult> SetGainModeAsync(GainMode mode)
        {
            return Task.Run(() =>
            {
                try
                {
                    var result = XISLApi.Acquisition_SetCameraGain(_hAcqDesc, (uint)mode);
                    if (result == XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        _gainMode = mode;
                        return DetectorResult.Success($"增益模式已设置为 {mode} | Gain mode set to {mode}");
                    }
                    return DetectorResult.Failure($"设置增益模式失败 | Failed to set gain mode: {result}");
                }
                catch (Exception ex)
                {
                    return DetectorResult.Failure($"设置增益模式异常 | Set gain mode exception: {ex.Message}", ex);
                }
            });
        }

        /// <summary>
        /// 获取增益模式 | Get gain mode
        /// </summary>
        public GainMode GetGainMode()
        {
            return _gainMode;
        }

        /// <summary>
        /// 设置曝光时间 | Set exposure time
        /// </summary>
        public Task<DetectorResult> SetExposureTimeAsync(uint milliseconds)
        {
            return Task.Run(() =>
            {
                try
                {
                    uint exposureTime = milliseconds;
                    var result = XISLApi.Acquisition_SetTimerSync(_hAcqDesc, ref exposureTime);
                    if (result == XISLApi.HIS_RETURN.HIS_ALL_OK)
                    {
                        _exposureTime = milliseconds;
                        return DetectorResult.Success($"曝光时间已设置为 {milliseconds} ms | Exposure time set to {milliseconds} ms");
                    }
                    return DetectorResult.Failure($"设置曝光时间失败 | Failed to set exposure time: {result}");
                }
                catch (Exception ex)
                {
                    return DetectorResult.Failure($"设置曝光时间异常 | Set exposure time exception: {ex.Message}", ex);
                }
            });
        }

        /// <summary>
        /// 获取曝光时间 | Get exposure time
        /// </summary>
        public uint GetExposureTime()
        {
            return _exposureTime;
        }

        /// <summary>
        /// 设置 ROI 区域 | Set ROI region
        /// </summary>
        public Task<DetectorResult> SetROIAsync(uint x, uint y, uint width, uint height)
        {
            return Task.Run(() =>
            {
                try
                {
                    // 注意：XISL API 可能需要特定的 ROI 设置函数
                    // 这里暂时只更新内部状态，实际 API 调用需要根据 XISL 文档补充
                    // Note: XISL API may require specific ROI setting functions
                    // Currently only updating internal state, actual API call needs to be added based on XISL documentation
                    _roi = (x, y, width, height);
                    return DetectorResult.Success($"ROI 区域已设置 | ROI region set: ({x}, {y}, {width}x{height})");
                }
                catch (Exception ex)
                {
                    return DetectorResult.Failure($"设置 ROI 区域异常 | Set ROI region exception: {ex.Message}", ex);
                }
            });
        }

        /// <summary>
        /// 获取 ROI 区域 | Get ROI region
        /// </summary>
        public (uint x, uint y, uint width, uint height) GetROI()
        {
            return _roi;
        }

        #endregion

        #region 回调函数（占位符）| Callback Functions (Placeholders)

        /// <summary>
        /// 帧结束回调函数 | End frame callback
        /// </summary>
        /// <param name="hAcqDesc">采集描述符句柄 | Acquisition descriptor handle</param>
        private void OnEndFrameCallback(IntPtr hAcqDesc)
        {
            try
            {
                uint dwRows = _cachedRows;
                uint dwColumns = _cachedColumns;
                int imageSize = (int)(dwRows * dwColumns);

                if (imageSize <= 0) return;

                // 分配独立数组（由消费者负责生命周期，避免 ArrayPool 竞态）
                // Allocate independent array (consumer owns lifetime, avoids ArrayPool race condition)
                ushort[] buffer = new ushort[imageSize];

                // 拷贝图像数据 | Copy image data
                unsafe
                {
                    fixed (ushort* pDest = buffer)
                    {
                        Buffer.MemoryCopy(
                            (void*)_pAcqBuffer,
                            pDest,
                            imageSize * sizeof(ushort),
                            imageSize * sizeof(ushort));
                    }
                }

                // 获取当前帧号 | Get current frame number
                int frameNumber = GetCurrentFrameNumber();

                // 创建事件参数 | Create event arguments
                var eventArgs = new ImageCapturedEventArgs
                {
                    ImageData = buffer,
                    Width = dwColumns,
                    Height = dwRows,
                    FrameNumber = frameNumber,
                    CaptureTime = DateTime.Now,
                    ExposureTime = _exposureTime,
                    SavePath = _config.SavePath
                };

                // 发布图像采集事件 | Publish image captured event
                PublishImageCaptured(eventArgs);
                _logger?.Debug($"图像采集完成，帧号：{frameNumber}，分辨率：{dwColumns}x{dwRows} | Image captured, frame: {frameNumber}, resolution: {dwColumns}x{dwRows}");

                // 设置帧结束事件 | Set frame end event
                if (_hevEndFrame != IntPtr.Zero)
                {
                    XISLApi.SetEvent(_hevEndFrame);
                }
            }
            catch (Exception ex)
            {
                var errorMsg = $"回调函数异常 | Callback exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                PublishError(errorResult);
            }
        }

        /// <summary>
        /// 采集结束回调函数 | End acquisition callback
        /// </summary>
        /// <param name="hAcqDesc">采集描述符句柄 | Acquisition descriptor handle</param>
        private void OnEndAcqCallback(IntPtr hAcqDesc)
        {
            try
            {
                // 重置板载选项 | Reset onboard options
                XISLApi.Acquisition_Reset_OnboardOptions(hAcqDesc);

                // 设置采集结束事件 | Set acquisition end event
                if (_hevEndAcq != IntPtr.Zero)
                {
                    XISLApi.SetEvent(_hevEndAcq);
                }
            }
            catch (Exception ex)
            {
                var errorResult = DetectorResult.Failure($"采集结束回调异常 | End acquisition callback exception: {ex.Message}", ex);
                PublishError(errorResult);
            }
        }

        #endregion

        #region 资源释放 | Resource Disposal

        /// <summary>
        /// 释放资源 | Dispose resources
        /// </summary>
        /// <param name="disposing">是否释放托管资源 | Whether to dispose managed resources</param>
        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _logger?.Info("开始释放 VarexDetector 资源 | Starting to dispose VarexDetector resources");

                if (disposing)
                {
                    // 释放托管资源 | Release managed resources
                    try
                    {
                        // 取消并释放采集取消令牌源 | Cancel and dispose acquisition cancellation token source
                        _acquisitionCts?.Cancel();
                        _acquisitionCts?.Dispose();
                        _acquisitionCts = null;
                        _logger?.Debug("采集取消令牌源已释放 | Acquisition cancellation token source disposed");
                    }
                    catch (Exception ex)
                    {
                        // 记录异常但继续释放其他资源 | Log exception but continue disposing other resources
                        _logger?.Warn($"释放 CancellationTokenSource 时发生异常 | Exception disposing CancellationTokenSource: {ex.Message}");
                        System.Diagnostics.Debug.WriteLine($"释放 CancellationTokenSource 时发生异常 | Exception disposing CancellationTokenSource: {ex.Message}");
                    }
                }

                // 释放非托管资源 | Release unmanaged resources
                try
                {
                    // 停止采集 | Stop acquisition
                    if (_hAcqDesc != IntPtr.Zero && _isAcquiring)
                    {
                        XISLApi.Acquisition_Abort(_hAcqDesc);
                        _isAcquiring = false;
                        _logger?.Debug("采集已停止 | Acquisition stopped");
                    }

                    // 关闭所有连接 | Close all connections
                    if (_hAcqDesc != IntPtr.Zero)
                    {
                        XISLApi.Acquisition_CloseAll();
                        _hAcqDesc = IntPtr.Zero;
                        _logger?.Debug("XISL 连接已关闭 | XISL connections closed");
                    }
                }
                catch (Exception ex)
                {
                    _logger?.Warn($"关闭 XISL 连接时发生异常 | Exception closing XISL connections: {ex.Message}");
                    System.Diagnostics.Debug.WriteLine($"关闭 XISL 连接时发生异常 | Exception closing XISL connections: {ex.Message}");
                }

                // 释放图像缓冲区 | Free image buffers
                try
                {
                    if (_pAcqBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(_pAcqBuffer);
                        _pAcqBuffer = IntPtr.Zero;
                    }

                    if (_pOffsetBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(_pOffsetBuffer);
                        _pOffsetBuffer = IntPtr.Zero;
                    }

                    if (_pGainBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(_pGainBuffer);
                        _pGainBuffer = IntPtr.Zero;
                    }

                    if (_pGainAvgBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(_pGainAvgBuffer);
                        _pGainAvgBuffer = IntPtr.Zero;
                    }

                    if (_pCorrList != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(_pCorrList);
                        _pCorrList = IntPtr.Zero;
                    }
                    _logger?.Debug("图像缓冲区已释放 | Image buffers freed");
                }
                catch (Exception ex)
                {
                    _logger?.Warn($"释放缓冲区时发生异常 | Exception freeing buffers: {ex.Message}");
                    System.Diagnostics.Debug.WriteLine($"释放缓冲区时发生异常 | Exception freeing buffers: {ex.Message}");
                }

                // 释放事件句柄 | Free event handles
                try
                {
                    if (_hevEndFrame != IntPtr.Zero)
                    {
                        XISLApi.CloseHandle(_hevEndFrame);
                        _hevEndFrame = IntPtr.Zero;
                    }

                    if (_hevEndAcq != IntPtr.Zero)
                    {
                        XISLApi.CloseHandle(_hevEndAcq);
                        _hevEndAcq = IntPtr.Zero;
                    }
                    _logger?.Debug("事件句柄已释放 | Event handles freed");
                }
                catch (Exception ex)
                {
                    _logger?.Warn($"释放事件句柄时发生异常 | Exception freeing event handles: {ex.Message}");
                    System.Diagnostics.Debug.WriteLine($"释放事件句柄时发生异常 | Exception freeing event handles: {ex.Message}");
                }

                _logger?.Info("VarexDetector 资源释放完成 | VarexDetector resources disposed");

                // 调用基类的 Dispose 方法 | Call base class Dispose method
                base.Dispose(disposing);
            }
        }

        #endregion
    }
}
