namespace SHH.CameraSdk;

/// <summary>
/// 截图协调器（单例模式）
/// 功能：桥接 API 线程的截图请求与 SDK 线程的帧数据推送，实现异步截图功能
/// 核心机制：基于 TaskCompletionSource 实现跨线程通信，支持超时控制与自动清理
/// 线程安全：全量使用并发容器，无锁设计，支持多设备同时请求截图
/// </summary>
public class SnapshotCoordinator
{
    #region --- 1. 单例实现 (Singleton Implementation) ---

    /// <summary> 全局唯一实例 </summary>
    public static SnapshotCoordinator Instance { get; } = new();

    /// <summary> 私有构造函数：禁止外部实例化，确保单例特性 </summary>
    private SnapshotCoordinator() { }

    #endregion

    #region --- 2. 私有任务池 (Private Task Pool) ---

    /// <summary> 待处理截图请求任务池（线程安全） </summary>
    /// <remarks> Key = 设备ID，Value = 任务完成源，用于传递截图结果或超时信号 </remarks>
    private readonly ConcurrentDictionary<long, TaskCompletionSource<byte[]>> _pendingRequests = new();

    #endregion

    #region --- 3. API 线程交互接口 (API Thread Interface) ---

    /// <summary>
    /// API 线程调用：申请指定设备的截图并异步等待结果
    /// </summary>
    /// <param name="deviceId">目标设备ID</param>
    /// <param name="timeoutMs">超时时间（默认 3000ms）</param>
    /// <returns>截图字节数组（JPEG/PNG 格式）/ 超时返回 null</returns>
    public async Task<byte[]?> RequestSnapshotAsync(long deviceId, int timeoutMs = 3000)
    {
        // 1. 创建任务完成源，用于接收 SDK 线程的截图数据
        var tcs = new TaskCompletionSource<byte[]>();
        // 2. 注册待处理请求到任务池
        _pendingRequests[deviceId] = tcs;

        try
        {
            // 3. 配置超时控制：超时后自动取消任务
            using var cts = new CancellationTokenSource(timeoutMs);
            using (cts.Token.Register(() => tcs.TrySetCanceled()))
            {
                // 4. 等待 SDK 线程推送截图数据
                return await tcs.Task.ConfigureAwait(false);
            }
        }
        catch (OperationCanceledException)
        {
            // 超时异常：返回 null 表示截图失败
            return null;
        }
        finally
        {
            // 5. 无论成功/超时，最终从任务池移除请求，防止内存泄漏
            _pendingRequests.TryRemove(deviceId, out _);
        }
    }

    #endregion

    #region --- 4. SDK 线程交互接口 (SDK Thread Interface) ---

    /// <summary>
    /// SDK 线程调用：检查指定设备是否存在待处理的截图请求
    /// </summary>
    /// <param name="deviceId">目标设备ID</param>
    /// <returns>存在待处理请求返回 true，否则返回 false</returns>
    public bool HasRequest(long deviceId) => _pendingRequests.ContainsKey(deviceId);

    /// <summary>
    /// SDK 线程调用：提交指定设备的截图数据，完成待处理请求
    /// </summary>
    /// <param name="deviceId">目标设备ID</param>
    /// <param name="data">截图字节数组（JPEG/PNG 格式）</param>
    public void ProvideSnapshot(long deviceId, byte[] data)
    {
        // 检查是否存在待处理请求，存在则推送数据并完成任务
        if (_pendingRequests.TryGetValue(deviceId, out var tcs))
        {
            tcs.TrySetResult(data);
        }
    }

    #endregion
}