using System;
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.Hardware.Detector.Factories;
using XP.Common.Logging.Interfaces;

namespace XP.Hardware.Detector.Services
{
    /// <summary>
    /// 探测器服务实现 | Detector service implementation
    /// 单例模式，封装业务逻辑，屏蔽厂商差异
    /// </summary>
    public class DetectorService : IDetectorService, IDisposable
    {
        private readonly IDetectorFactory _factory;
        private readonly IEventAggregator _eventAggregator;
        private readonly ILoggerService _logger;
        private readonly object _lock = new object();
        private IAreaDetector _detector;
        private DetectorConfig _config;
        private DetectorResult _lastError;
        private bool _disposed = false;

        /// <summary>
        /// 当前探测器状态 | Current detector status
        /// </summary>
        public DetectorStatus Status
        {
            get
            {
                lock (_lock)
                {
                    return _detector?.Status ?? DetectorStatus.Uninitialized;
                }
            }
        }

        /// <summary>
        /// 当前探测器类型 | Current detector type
        /// </summary>
        public DetectorType? Type
        {
            get
            {
                lock (_lock)
                {
                    return _detector?.Type;
                }
            }
        }

        /// <summary>
        /// 探测器是否已连接 | Whether detector is connected
        /// </summary>
        public bool IsConnected
        {
            get
            {
                lock (_lock)
                {
                    return _detector != null && _detector.Status != DetectorStatus.Uninitialized;
                }
            }
        }

        /// <summary>
        /// 构造函数 | Constructor
        /// </summary>
        /// <param name="factory">探测器工厂 | Detector factory</param>
        /// <param name="eventAggregator">事件聚合器 | Event aggregator</param>
        /// <param name="logger">日志服务 | Logger service</param>
        public DetectorService(IDetectorFactory factory, IEventAggregator eventAggregator, ILoggerService logger = null)
        {
            _factory = factory ?? throw new ArgumentNullException(nameof(factory));
            _eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
            _logger = logger?.ForModule("DetectorService");
            _logger?.Info("DetectorService 实例已创建 | DetectorService instance created");
        }

        /// <summary>
        /// 初始化探测器 | Initialize detector
        /// </summary>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> InitializeAsync(CancellationToken cancellationToken = default)
        {
            // 若已连接，先断开再重连 | If already connected, disconnect first then reconnect
            bool alreadyConnected;
            lock (_lock) { alreadyConnected = _detector != null; }
            if (alreadyConnected)
            {
                _logger?.Info("探测器已连接，先断开再重新初始化 | Detector already connected, disconnecting before reinitializing");
                await DisconnectAsync();
            }

            try
            {
                _logger?.Info("开始初始化探测器服务 | Starting to initialize detector service");

                // 加载配置 | Load configuration
                _logger?.Debug("加载配置文件 | Loading configuration file");
                var configResult = ConfigLoader.LoadConfiguration();
                if (!configResult.IsSuccess)
                {
                    _lastError = configResult;
                    _logger?.Error(null, $"加载配置失败 | Failed to load configuration: {configResult.ErrorMessage}");
                    return configResult;
                }
                _logger?.Info($"配置加载成功，探测器类型：{configResult.Data.Type} | Configuration loaded successfully, detector type: {configResult.Data.Type}");

                // 保存配置引用 | Save config reference
                _config = configResult.Data;

                // 创建探测器实例 | Create detector instance
                _logger?.Debug("创建探测器实例 | Creating detector instance");
                var createResult = _factory.CreateDetector(configResult.Data);
                if (!createResult.IsSuccess)
                {
                    _lastError = createResult;
                    _logger?.Error(createResult.Exception, $"创建探测器实例失败 | Failed to create detector instance: {createResult.ErrorMessage}");
                    return DetectorResult.Failure(createResult.ErrorMessage, createResult.Exception, createResult.ErrorCode);
                }

                lock (_lock)
                {
                    _detector = createResult.Data;
                }

                // 初始化探测器 | Initialize detector
                _logger?.Debug("初始化探测器硬件 | Initializing detector hardware");
                var initResult = await _detector.InitializeAsync(cancellationToken);
                if (!initResult.IsSuccess)
                {
                    _lastError = initResult;
                    _logger?.Error(initResult.Exception, $"初始化探测器硬件失败 | Failed to initialize detector hardware: {initResult.ErrorMessage}");
                }
                else
                {
                    _logger?.Info("探测器服务初始化成功 | Detector service initialized successfully");
                }

                return initResult;
            }
            catch (Exception ex)
            {
                var errorMsg = $"初始化服务失败 | Failed to initialize service: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 断开探测器连接 | Disconnect detector
        /// </summary>
        public async Task<DetectorResult> DisconnectAsync()
        {
            try
            {
                IAreaDetector detector;
                lock (_lock)
                {
                    detector = _detector;
                    if (detector == null)
                    {
                        _logger?.Warn("探测器未连接，无需断开 | Detector not connected, no need to disconnect");
                        return DetectorResult.Success("探测器未连接 | Detector not connected");
                    }
                }

                _logger?.Info("开始断开探测器连接 | Starting to disconnect detector");

                // 如果正在采集，先停止 | If acquiring, stop first
                if (detector.Status == DetectorStatus.Acquiring)
                {
                    _logger?.Info("探测器正在采集，先停止采集 | Detector is acquiring, stopping first");
                    await detector.StopAcquisitionAsync();
                }

                // 释放探测器资源 | Dispose detector resources
                lock (_lock)
                {
                    _detector?.Dispose();
                    _detector = null;
                }

                _config = null;
                _logger?.Info("探测器已断开连接 | Detector disconnected");
                return DetectorResult.Success("探测器已断开连接 | Detector disconnected");
            }
            catch (Exception ex)
            {
                var errorMsg = $"断开探测器连接异常 | Disconnect detector exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                // 强制清理 | Force cleanup
                lock (_lock)
                {
                    _detector?.Dispose();
                    _detector = null;
                }
                _config = null;
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 启动连续采集 | Start continuous acquisition
        /// </summary>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> StartAcquisitionAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：启动连续采集 | Service layer: Starting continuous acquisition");
                var detector = GetDetectorOrThrow();
                var result = await detector.StartAcquisitionAsync(cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, $"启动采集失败 | Failed to start acquisition: {result.ErrorMessage}");
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层启动采集异常 | Service layer start acquisition exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 停止采集 | Stop acquisition
        /// </summary>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> StopAcquisitionAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：停止采集 | Service layer: Stopping acquisition");
                var detector = GetDetectorOrThrow();
                var result = await detector.StopAcquisitionAsync(cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, $"停止采集失败 | Failed to stop acquisition: {result.ErrorMessage}");
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层停止采集异常 | Service layer stop acquisition exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 单帧采集 | Single frame acquisition
        /// </summary>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> AcquireSingleFrameAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Debug("服务层：单帧采集 | Service layer: Single frame acquisition");
                var detector = GetDetectorOrThrow();
                var result = await detector.AcquireSingleFrameAsync(cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, $"单帧采集失败 | Failed to acquire single frame: {result.ErrorMessage}");
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层单帧采集异常 | Service layer single frame acquisition exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 暗场校正 | Dark field correction
        /// </summary>
        /// <param name="frameCount">采集帧数 | Frame count</param>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> DarkCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：执行暗场校正，帧数：{FrameCount} | Service layer: Executing dark correction, frame count: {FrameCount}", frameCount);
                var detector = GetDetectorOrThrow();
                var result = await detector.DarkCorrectionAsync(frameCount, cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, "暗场校正失败：{Message} | Dark correction failed: {Message}", result.ErrorMessage);
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层暗场校正异常 | Service layer dark correction exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 增益校正（亮场校正）| Gain correction (bright field correction)
        /// </summary>
        /// <param name="frameCount">采集帧数 | Frame count</param>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> GainCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：执行亮场校正，帧数：{FrameCount} | Service layer: Executing gain correction, frame count: {FrameCount}", frameCount);
                var detector = GetDetectorOrThrow();
                var result = await detector.GainCorrectionAsync(frameCount, cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, "亮场校正失败：{Message} | Gain correction failed: {Message}", result.ErrorMessage);
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层亮场校正异常 | Service layer gain correction exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 坏像素校正 | Bad pixel correction
        /// </summary>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> BadPixelCorrectionAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：执行坏像素校正 | Service layer: Executing bad pixel correction");
                var detector = GetDetectorOrThrow();
                var result = await detector.BadPixelCorrectionAsync(cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, "坏像素校正失败：{Message} | Bad pixel correction failed: {Message}", result.ErrorMessage);
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层坏像素校正异常 | Service layer bad pixel correction exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 执行自动校正（暗场+增益+坏像素）| Execute auto correction (dark + gain + bad pixel)
        /// </summary>
        /// <param name="frameCount">采集帧数 | Frame count</param>
        /// <param name="cancellationToken">取消令牌 | Cancellation token</param>
        /// <returns>操作结果 | Operation result</returns>
        public async Task<DetectorResult> AutoCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：执行自动校正，帧数：{FrameCount} | Service layer: Executing auto correction, frame count: {FrameCount}", frameCount);
                var detector = GetDetectorOrThrow();
                var result = await detector.AutoCorrectionAsync(frameCount, cancellationToken);
                if (!result.IsSuccess)
                {
                    _lastError = result;
                    _logger?.Error(result.Exception, "自动校正失败：{Message} | Auto correction failed: {Message}", result.ErrorMessage);
                }
                return result;
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层自动校正异常 | Service layer auto correction exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 应用探测器参数（Binning/PGA/帧率统一下发）| Apply detector parameters (Binning/PGA/FrameRate)
        /// </summary>
        public async Task<DetectorResult> ApplyParametersAsync(int binningIndex, int pga, decimal frameRate, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.Info("服务层：应用参数，Binning={Binning}，PGA={PGA}，帧率={FrameRate} | Service layer: Applying parameters",
                    binningIndex, pga, frameRate);

                var detector = GetDetectorOrThrow();

                // 通过 IVarexDetector 接口下发参数 | Apply parameters via IVarexDetector interface
                if (detector is IVarexDetector varexDetector)
                {
                    // 设置 Binning | Set binning
                    var binningResult = await varexDetector.SetBinningModeAsync((BinningMode)binningIndex);
                    if (!binningResult.IsSuccess)
                    {
                        _lastError = binningResult;
                        return binningResult;
                    }

                    // 设置增益（PGA）| Set gain (PGA)
                    var gainResult = await varexDetector.SetGainModeAsync((GainMode)pga);
                    if (!gainResult.IsSuccess)
                    {
                        _lastError = gainResult;
                        return gainResult;
                    }

                    // 设置曝光时间（帧率→微秒：1000*1000/帧率）| Set exposure time (frame rate → microseconds)
                    uint exposureUs = frameRate > 0 ? (uint)(1_000_000m / frameRate) : 66667;
                    var exposureResult = await varexDetector.SetExposureTimeAsync(exposureUs);
                    if (!exposureResult.IsSuccess)
                    {
                        _lastError = exposureResult;
                        return exposureResult;
                    }

                    _logger?.Info("参数应用成功 | Parameters applied successfully");
                    return DetectorResult.Success("参数应用成功 | Parameters applied successfully");
                }

                return DetectorResult.Failure("当前探测器不支持参数下发 | Current detector does not support parameter application");
            }
            catch (Exception ex)
            {
                var errorMsg = $"服务层应用参数异常 | Service layer apply parameters exception: {ex.Message}";
                _logger?.Error(ex, errorMsg);
                var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
                _lastError = errorResult;
                return errorResult;
            }
        }

        /// <summary>
        /// 保存当前配置到文件 | Save current configuration to file
        /// </summary>
        public void SaveParameters(int binningIndex, int pga, decimal frameRate, int avgFrames)
        {
            try
            {
                _logger?.Info("保存探测器参数，Binning={Binning}，PGA={PGA}，帧率={FrameRate}，帧合并={AvgFrames} | Saving detector parameters",
                    binningIndex, pga, frameRate, avgFrames);
                ConfigLoader.SaveParameters(binningIndex, pga, frameRate, avgFrames);
                _logger?.Info("探测器参数保存成功 | Detector parameters saved successfully");
            }
            catch (Exception ex)
            {
                _logger?.Error(ex, "保存探测器参数失败：{Message} | Failed to save detector parameters: {Message}", ex.Message);
            }
        }

        /// <summary>
        /// 获取探测器信息 | Get detector information
        /// </summary>
        /// <returns>探测器信息 | Detector information</returns>
        public DetectorInfo GetInfo()
        {
            var detector = GetDetectorOrThrow();
            return detector.GetInfo();
        }

        /// <summary>
        /// 获取最后的错误信息 | Get last error information
        /// </summary>
        /// <returns>错误结果 | Error result</returns>
        public DetectorResult GetLastError()
        {
            return _lastError ?? DetectorResult.Success();
        }

        /// <summary>
        /// 获取当前探测器配置 | Get current detector configuration
        /// 未初始化时尝试从配置文件加载（仅读取配置，不创建探测器实例）
        /// </summary>
        public DetectorConfig GetCurrentConfig()
        {
            if (_config != null) return _config;

            // 未初始化时，尝试从配置文件加载以提供 UI 选项 | If not initialized, try loading from config for UI options
            try
            {
                var configResult = ConfigLoader.LoadConfiguration();
                if (configResult.IsSuccess)
                {
                    _config = configResult.Data;
                    return _config;
                }
            }
            catch
            {
                // 忽略加载异常，返回 null | Ignore load exception, return null
            }
            return null;
        }

        /// <summary>
        /// 获取探测器实例或抛出异常 | Get detector instance or throw exception
        /// </summary>
        /// <returns>探测器实例 | Detector instance</returns>
        /// <exception cref="InvalidOperationException">探测器未初始化 | Detector not initialized</exception>
        private IAreaDetector GetDetectorOrThrow()
        {
            lock (_lock)
            {
                if (_detector == null)
                {
                    throw new InvalidOperationException("探测器未初始化，请先调用 InitializeAsync | Detector not initialized, please call InitializeAsync first");
                }
                return _detector;
            }
        }

        /// <summary>
        /// 释放资源 | Dispose resources
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 释放资源 | Dispose resources
        /// </summary>
        /// <param name="disposing">是否释放托管资源 | Whether to dispose managed resources</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // 释放托管资源 | Release managed resources
                    lock (_lock)
                    {
                        _detector?.Dispose();
                        _detector = null;
                    }
                }
                _disposed = true;
            }
        }
    }
}
