namespace SHH.CameraSdk;

/// <summary>
/// 帧需求定义模型
/// 功能：描述某个程序/模块对视频帧的消费需求，用于帧分发调度与帧率控制
/// 用途：配合 FrameController，实现按订阅者需求精准分配帧资源，避免资源浪费
/// </summary>
public class FrameRequirement
{
    public FrameRequirement()
    {
    }

    public FrameRequirement(SubscriptionDto dto)
    {
        // 1. 核心标识
        this.AppId = dto.AppId;
        this.Type = dto.Type;

        // 2. 流控参数
        this.TargetFps = dto.DisplayFps;

        // 3. 业务动态参数
        this.Memo = dto.Memo;
        this.Handle = dto.Handle;
        this.RecordDuration = dto.RecordDuration;
        this.SavePath = dto.SavePath;

        // 4. 网络转发相关参数 (补全)
        this.Protocol = dto.Protocol;
        this.TargetIp = dto.TargetIp;
        this.TargetPort = dto.TargetPort;

        // 5. 初始化内部统计状态
        this.LastCaptureTick = Environment.TickCount64;
        this._lastFpsCalcTick = Environment.TickCount64;
        this.IsActive = true;
    }

    #region --- 订阅者核心标识 (Subscriber Core Identification) ---

    /// <summary> 订阅者唯一ID（如 "Client_A"、"AI_Service"、"WPF_Display_Main"） </summary>
    /// <remarks> 用于区分不同的帧消费模块，作为帧分发路由的关键标识 </remarks>
    public string AppId { get; set; } = string.Empty;

    /// <summary> 订阅业务类型（描述视频流的最终去向和处理逻辑） </summary>
    /// <remarks> 决定了后端流控引擎后续的资源分配（如录像机或渲染器） </remarks>
    public SubscriptionType Type { get; set; } = SubscriptionType.LocalWindow;

    #endregion

    #region --- 帧率控制参数 (Frame Rate Control Parameters) ---

    /// <summary> 目标帧率（单位：fps，订阅者期望的每秒接收帧数） </summary>
    /// <remarks> 范围 1-25 fps。例如：UI 预览需 15fps，AI 分析需 5fps </remarks>
    public int TargetFps { get; set; } = 15;

    /// <summary> 上次成功分发帧的时间点（单位：毫秒，基于 Environment.TickCount64） </summary>
    /// <remarks> 帧率控制算法的核心，用于判断当前时刻是否应向此订阅者推送帧 </remarks>
    public long LastCaptureTick { get; set; } = 0;

    #endregion

    #region --- 业务动态参数 (Business Dynamic Parameters) ---

    /// <summary> 备注信息（记录订阅用途、申请人或关联业务系统） </summary>
    public string Memo { get; set; } = string.Empty;

    /// <summary> 窗口句柄（仅在 Type 为 HandleDisplay 时有效） </summary>
    /// <remarks> 格式通常为十六进制或十进制字符串，用于跨进程或底层渲染对接 </remarks>
    public string Handle { get; set; } = string.Empty;

    /// <summary> 录像持续时长（单位：分钟，仅在 Type 为 LocalRecord 时有效） </summary>
    public int RecordDuration { get; set; } = 5;

    /// <summary> 录像存放路径（仅在 Type 为 LocalRecord 时有效） </summary>
    /// <remarks> 服务器本地磁盘的绝对路径，例如：D:\Recordings\Camera_01 </remarks>
    public string SavePath { get; set; } = string.Empty;

    /// <summary> 通讯传输协议（仅在网络转发模式下有效） </summary>
    public TransportProtocol Protocol { get; set; }
        = TransportProtocol.Tcp;

    /// <summary> 目标接收端 IP 地址（仅在网络转发模式下有效） </summary>
    public string TargetIp { get; set; } = "127.0.0.1";

    /// <summary> 目标接收端端口号（仅在网络转发模式下有效） </summary>
    public int TargetPort { get; set; } = 8080;

    #endregion

    #region --- 运行统计与控制 (Runtime Stats & Control) ---

    /// <summary> 实时计算的输出帧率（单位：fps，实际分发给订阅者的频率） </summary>
    /// <remarks> 反映系统真实运行状态，若低于 TargetFps 则说明分发链路存在瓶颈 </remarks>
    public double RealFps { get; set; } = 0.0;

    /// <summary> 需求是否激活（true=正常接收帧，false=暂停接收，保留配置） </summary>
    public bool IsActive { get; set; } = true;

    #endregion

    #region --- 内部逻辑控制 (Internal Logic Control) ---

    private int _frameCount = 0;
    private long _lastFpsCalcTick = Environment.TickCount64;

    /// <summary>
    /// 更新实际帧率统计
    /// </summary>
    /// <remarks> 每当成功分发一帧后调用，内部自动按秒计算 RealFps </remarks>
    public void UpdateRealFps()
    {
        try
        {
            _frameCount++;
            long currentTick = Environment.TickCount64;
            long elapsed = currentTick - _lastFpsCalcTick;

            if (elapsed >= 1000) // 达到 1 秒周期
            {
                RealFps = Math.Round(_frameCount / (elapsed / 1000.0), 1);
                _frameCount = 0;
                _lastFpsCalcTick = currentTick;
            }
        }
        catch{ }
    }

    #endregion
}