using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

namespace SHH.CameraDashboard
{
    public partial class CameraRepository
    {
        // 文件: Services\WebApis\CameraReps\CameraRepository.cs

        public async Task<bool> UpdateSubscriptionAsync(long cameraId, SubscriptionDto dto)
        {
            var serviceNode = AppGlobal.UseServiceNode;
            if (serviceNode == null) return false;

            // URL: POST /api/Cameras/{id}/subscriptions
            string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions";

            try
            {
                string jsonBody = JsonHelper.Serialize(dto);
                // 发送 POST 请求
                await WebApiService.Instance.PostAsync(requestUrl, jsonBody, "更新订阅配置");
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"更新订阅失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// [新增] 获取订阅列表
        /// </summary>
        public async Task<List<SubscriptionDto>> GetSubscriptionsAsync(long cameraId)
        {
            var serviceNode = AppGlobal.UseServiceNode;
            if (serviceNode == null) return new List<SubscriptionDto>();

            // URL: GET /api/Cameras/{id}/subscriptions
            string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions";

            try
            {
                string json = await WebApiService.Instance.GetAsync(requestUrl, "获取订阅列表");

                // 如果返回空或null，返回空列表
                if (string.IsNullOrEmpty(json)) return new List<SubscriptionDto>();

                var list = JsonHelper.Deserialize<List<SubscriptionDto>>(json);
                return list ?? new List<SubscriptionDto>();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"获取订阅列表失败: {ex.Message}");
                return new List<SubscriptionDto>();
            }
        }

        /// <summary>
        /// [修改] 删除/注销订阅
        /// 改为标准的 DELETE 请求
        /// </summary>
        public async Task<bool> DeleteSubscriptionAsync(long cameraId, string appId)
        {
            if (string.IsNullOrWhiteSpace(appId)) return false;

            var serviceNode = AppGlobal.UseServiceNode;
            if (serviceNode == null) return false;

            // 拼接 URL: DELETE /api/Cameras/1001/subscriptions/Client_01
            // 注意：AppId 如果包含特殊字符，建议 UrlEncode，但一般 ID 都是字母数字
            string requestUrl = $"http://{serviceNode.ServiceNodeIp}:{serviceNode.ServiceNodePort}{WebApiRoutes.Cameras.Root}/{cameraId}/subscriptions/{appId}";

            try
            {
                // 调用刚刚在 WebApiService 里加的 DeleteAsync
                await WebApiService.Instance.DeleteAsync(requestUrl, "注销订阅");
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"注销订阅失败: {ex.Message}");
                return false;
            }
        }
    }

    /// <summary>
    /// 视频流订阅配置请求对象
    /// 用于定义第三方应用或内部模块对指定相机流的消费需求
    /// </summary>
    public class SubscriptionDto
    {
        /// <summary>
        /// 进程唯一标识 (如 "AI_Process_01"、"Main_Display_02")
        /// </summary>
        public string AppId { get; set; } = string.Empty;

        /// <summary>
        /// 订阅业务类型。
        /// 决定了后端流控引擎后续的资源分配（如是否开启录像机或渲染器）。
        /// </summary>
        public int Type { get; set; }

        /// <summary>
        /// 显示帧率需求 (单位: fps)
        /// <para>不需要显示则设为 0，控制器会自动注销该类型需求</para>
        /// </summary>
        public int DisplayFps
        {
            get => TargetFps;
            set => TargetFps = value;
        }
        
        public int TargetFps { get; set; }

        /// <summary>
        /// [新增] 实际显示/分发帧率
        /// JSON: "realFps"
        /// </summary>
        [JsonPropertyName("realFps")]
        public double RealFps { get; set; }

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

        /// <summary>
        /// 窗口句柄（HWND）。
        /// 仅在 Type 为 HandleDisplay 时必填。格式通常为十六进制或十进制字符串。
        /// </summary>
        public string Handle { get; set; }
            = string.Empty;

        /// <summary>
        /// 录像持续时长（分钟，范围 1-60）。
        /// 仅在 Type 为 LocalRecord 时有效。
        /// </summary>
        public int RecordDuration { get; set; }

        /// <summary>
        /// 录像文件存放绝对路径。
        /// 仅在 Type 为 LocalRecord 时有效，例如：C:\Recordings\Room01。
        /// </summary>
        public string SavePath { get; set; }
            = string.Empty;

        /// <summary>
        /// 通讯方式协议。
        /// 仅在 Type 为 NetworkTrans 或 WebPush 时有效，默认为 Network。
        /// </summary>
        public int Protocol { get; set; }

        /// <summary>
        /// 目标接收端 IP 地址。
        /// 仅在 Type 为 NetworkTrans 或 WebPush 且 Protocol 为 Network 时必填。
        /// </summary>
        public string TargetIp { get; set; }
            = string.Empty;

        /// <summary>
        /// 目标接收端端口号。
        /// 仅在 Type 为 NetworkTrans 或 WebPush 时必填。
        /// </summary>
        public int TargetPort { get; set; }
    }

    /// <summary>
    /// 订阅业务类型枚举
    /// 描述视频流的最终去向和业务用途，用于帧分发策略的路由决策
    /// </summary>
    public enum SubscriptionType
    {
        /// <summary>
        /// 本地窗口渲染
        /// <para>直接在服务器端显示器绘制（如 OpenCV Window、WinForm 控件）</para>
        /// </summary>
        [Description("本地窗口显示")]
        LocalWindow = 0,

        /// <summary>
        /// 本地录像存储
        /// <para>写入磁盘文件（如 MP4/AVI 格式，支持定时切割、循环覆盖）</para>
        /// </summary>
        [Description("本地录像存储")]
        LocalRecord = 1,

        /// <summary>
        /// 句柄绑定显示
        /// <para>渲染到指定 HWND 窗口句柄（如 SDK 硬件解码渲染到客户端控件）</para>
        /// </summary>
        [Description("句柄绑定显示")]
        HandleDisplay = 2,

        /// <summary>
        /// 自定义网络传输
        /// <para>通过私有协议转发给第三方系统（如工控机、告警服务器）</para>
        /// </summary>
        [Description("自定义网络传输")]
        NetworkTrans = 3,

        /// <summary>
        /// 网页端推流
        /// <para>转码为 Web 标准协议（如 WebRTC、HLS、RTMP）供浏览器播放</para>
        /// </summary>
        [Description("网页端推流")]
        WebPush = 4
    }

    /// <summary>
    /// 网络传输协议类型
    /// </summary>
    public enum TransportProtocol
    {
        /// <summary> 可靠传输 (默认) </summary>
        Tcp = 0,

        /// <summary> 快速传输 (可能丢包/花屏) </summary>
        Udp = 1,

        /// <summary> 组播 (节省带宽) </summary>
        Multicast = 2,

        /// <summary> 内存交互 </summary>
        Memory = 99,
    }
}
