using System.Drawing;
using System.Drawing.Imaging;
using System.Net.WebSockets;
using System.Text;
using MoYu.DataEncryption;
using MoYu.RemoteRequest.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SafeCampus.Application.Services.Business.AttendanceService;
using SafeCampus.Application.Services.Business.ClassRoomCallService;
using SafeCampus.Application.Services.Business.Warn.Dto;
using SafeCampus.Application.Services.Business.Warn.Service;

namespace SafeCampus.Application.Manager.DeepelephManager;
/// <summary>
/// 深象智能对接实现
/// </summary>
public class DeepelephManager : IDeepelephManager, IScoped
{

    private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
    private bool _isConnected = false;
    private Timer _pingTimer;
    private List<ClientWebSocket> webScokets=new List<ClientWebSocket>();
    private readonly ISimpleCacheService _simpleCacheService;

    public DeepelephManager(ISimpleCacheService simpleCacheService)
    {
        _simpleCacheService = simpleCacheService;
    }

    //获取地址
    //建立请求,发送订阅参数
    //遍历等待接收消息
    public string GetToken()
    {
        var cacheToken = _simpleCacheService.Get<string>(AuthConstants.SXTOKEN);
        if (cacheToken != null) return cacheToken;
        return GenSXToken();
    }
    /// <summary>
    /// 获取深象智能Token
    /// </summary>
    /// <returns></returns>
    private string GenSXToken()
    {
        var token = "";
        var setting = App.GetOptionsMonitor<AppInfoOptions>();
        var nonce = Guid.NewGuid().ToString("N");
        var timestamp =DateTimeOffset.Now.ToUnixTimeMilliseconds();
        var list =  $"{setting.SXAPIURL}/user/center/v1/login/client"
            .SetBody(new
            {
                appKey = setting.AppKey, 
                appSecret = setting.AppSecret,
                nonce ,
                timestamp,
                sign = MD5Encryption.Encrypt($"{setting.AppSecret}appKey{setting.AppKey}nonce{nonce}timestamp{timestamp}{setting.AppSecret}",true)
            })
            .SetContentType("application/json")
            .PostAsAsync<string>().Result;
        var model = JsonConvert.DeserializeObject<JObject>(list);
        if (model["success"]!=null)
        {
            if ((bool)model["success"])
            {
                token = model["data"]["token"].ToString();
                //token有效期2小时,提前20分钟失效
                _simpleCacheService.Set(AuthConstants.SXTOKEN, token, 100*60);
            }
            else
            {
                LogHelper.WriteToLog("token请求失败", model["message"].ToString());
            }
        }

        return token;
    }
    /// <summary>
    /// 订阅预警更新
    /// </summary>
    /// <returns></returns>
    public async Task SubscribeAlarm()
    {
        var setting = App.GetOptionsMonitor<AppInfoOptions>();
        var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        var url = GetWebSocketUrl(AuthConstants.SXALARM, AuthConstants.SXALARM_Grpup);
        var subscribeJson = JsonConvert.SerializeObject(new
        {
            token = GetToken(),
            type = "subscribe",
            timestamp,
            payload = new
            {
                topic = AuthConstants.SXALARM, consumerGroup = AuthConstants.SXALARM_Grpup, tags = setting.TenantCode
            }
        });
        ClientWebSocket _webSocket = new ClientWebSocket();
        webScokets.Add(_webSocket);
        await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None);
        //LogHelper.WriteToLog($"预警WebSocket 地址:{url}");
        await _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None);
        byte[] buffer = new byte[1024*8];
        while (_webSocket.State == WebSocketState.Open)
        {
            //try
            //{
            //    var jsonstr =
            //   "{\"body\":{\"extend\":\"{\\\"trackId\\\":\\\"7173252404809024768\\\",\\\"genderScore\\\":[0.0,1.0,0.0],\\\"faceSnapshot\\\":\\\"http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240719/edge/group/SXT001_book_wm_1721360996798_55.jpg?Expires=1721368200&OSSAccessKeyId=STS.NSwBDiH7ZnNGS9m2ahE8XyuW6&Signature=dEBXyrWcz3FyXMqDueIkZL%2F9uhk%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5DCCf7dpeh72YysUR%2Fc1mE9Sbd0lrD81Dz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4zJySB7g0s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKTpyjlP%2FAxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39ay%2BVK8NrfsIeBqAATzzKDWbI1DbvfIwuHS6%2BX5i%2FQ0%2BgbpA87Kw%2BQiZxZdvjHXLLqQaYmTRXkuFPxUqNR8BckkEiPPkSs%2B9UQm3Cwq6rnEFeZty8FvEKds5Wo3H2QevhGwkKNImDp%2BmIjF2gzxOSfDv5rBvJWanWW0ewZdlFeiIR88SRvtr10jyoV4OIAA%3D\\\",\\\"faceSnapshotPath\\\":\\\"deepvision:acp/quanjiang/DEMO00001/20240719/edge/group/SXT001_book_wm_1721360996798_55.jpg\\\",\\\"faceScore\\\":30.105469}\",\"alarmType\":\"mask_detect\",\"func\":\"mask_detect\",\"cameraId\":\"SXT001\",\"alarmId\":\"1600d5874d854f1da54e663ae56c845f\",\"snapshotUrl\":\"http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240719/edge/group/SXT001/SXT001_69bde610-a957-434b-a7ce-834aee148b2b_wm_56.jpg?Expires=1721368200&OSSAccessKeyId=STS.NSwBDiH7ZnNGS9m2ahE8XyuW6&Signature=hb6DQLWwZqukNQdel0TsUctAwAE%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5DCCf7dpeh72YysUR%2Fc1mE9Sbd0lrD81Dz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4zJySB7g0s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKTpyjlP%2FAxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39ay%2BVK8NrfsIeBqAATzzKDWbI1DbvfIwuHS6%2BX5i%2FQ0%2BgbpA87Kw%2BQiZxZdvjHXLLqQaYmTRXkuFPxUqNR8BckkEiPPkSs%2B9UQm3Cwq6rnEFeZty8FvEKds5Wo3H2QevhGwkKNImDp%2BmIjF2gzxOSfDv5rBvJWanWW0ewZdlFeiIR88SRvtr10jyoV4OIAA%3D\",\"rects\":[{\"top\":601,\"left\":1156,\"width\":235,\"height\":767}],\"poiId\":\"DEMO00001\",\"tenantCode\":\"quanjiang\",\"tick\":1721360953398},\"bornTimestamp\":1721361000758,\"consumerGroup\":\"GID_quanjiang_risk\",\"keys\":\"1600d5874d854f1da54e663ae56c845f\",\"messageId\":\"AC14058A00017A07C5B45F3C813680EC\",\"queueId\":4,\"queueOffset\":422853,\"tags\":\"quanjiang\",\"topic\":\"ECOLOGY_PAAS_RISK_ALARM\",\"type\":\"msg\"}";
            //    var json = JsonConvert.DeserializeObject<JObject>(jsonstr);
            //    if (json["type"].ToString() == "msg")
            //    {
            //        var body = json["body"];
            //        if (body != null)
            //        {
            //            PersonType personEnum;
            //            if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum))
            //            {
            //                dayEnum = AlarmType.visual_fence;
            //            }

            //            if (body["extend"] != null)
            //            {
            //                var extend = JsonConvert.DeserializeObject<JObject>(body["extend"].ToString());
            //                if (extend["personType"] != null)
            //                {
            //                    if (!Enum.TryParse(body["extend"]?["personType"]?.ToString(), out personEnum))
            //                    {
            //                        personEnum = PersonType.unkonwn;
            //                    }
            //                }
            //                else
            //                {
            //                    personEnum = PersonType.unkonwn;
            //                }

            //            }
            //            else
            //            {
            //                personEnum = PersonType.unkonwn;
            //            }

            //            var model = new WarnInfoDto
            //            {
            //                TenantCode = body["tenantCode"]?.ToString(),
            //                PoiId = body["poiId"]?.ToString(),
            //                AlarmId = body["alarmId"]?.ToString(),
            //                AlarmType = body["alarmType"]?.ToString(),
            //                AlarmTypeDesc = dayEnum.GetDescription(),
            //                CameraId = body["cameraId"]?.ToString(),
            //                Tick = TimestampToDateTime(body["tick"].ToString()),
            //                SnapshotUrl = body["snapshotUrl"]?.ToString(),
            //                Rects = body["rects"]?.ToString(),
            //                Tags = body["tags"]?.ToString(),
            //                Extend = body["extend"]?.ToString(),
            //                PersonType = personEnum.GetDescription(),
            //                WarnHand = 0,
            //            };
            //            var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.AlarmId + ".jpg");
            //            var steam = await model.SnapshotUrl.GetAsByteArrayAsync();
            //            model.SnapshotUrl = $"http://192.168.10.186:8003/Files/alarmImg/{model.AlarmId}.jpg";
            //            using (MemoryStream ms = new MemoryStream(steam))
            //            {
            //                using (Bitmap bmp = new Bitmap(ms))
            //                {
            //                    using (Graphics g = Graphics.FromImage(bmp))
            //                    {
            //                        using (Pen pen = new Pen(Color.Red, 3))
            //                        {
            //                            foreach (var item in body["rects"])
            //                            {
            //                                Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]);
            //                                g.DrawRectangle(pen, rect);
            //                            }
            //                        }
            //                    }
            //                    bmp.Save(signImg, ImageFormat.Jpeg);
            //                }
            //            }
            //            //await model.SnapshotUrl.GetToSaveAsync(signImg);
            //            Scoped.Create((_, scope) =>
            //            {
            //                var services = scope.ServiceProvider;
            //                var _repository = services.GetService<IWarnInfoService>();
            //                _repository.Add(model);
            //            });
            //        }
            //    }
            //}
            //catch (Exception e)
            //{

            //}

            WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            if (result.MessageType == WebSocketMessageType.Text)
            {
                try
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    var json = JsonConvert.DeserializeObject<JObject>(message);
                    if (json["type"].ToString() == "msg")
                    {

                        //TODO 发送短信
                        //TxySmsUtil.SendSms(new[] { "" }, new[] { "" });
                        var body = json["body"];
                        if (body != null)
                        {
                            var model = new WarnInfoDto
                            {
                                TenantCode = body["tenantCode"]?.ToString(),
                                PoiId = body["poiId"]?.ToString(),
                                AlarmId = body["alarmId"]?.ToString(),
                                AlarmType = body["alarmType"]?.ToString(),
                                //AlarmTypeDesc = dayEnum.GetDescription(),
                                CameraId = body["cameraId"]?.ToString(),
                                Tick = TimestampToDateTime(body["tick"].ToString()),
                                SnapshotUrl = body["snapshotUrl"]?.ToString(),
                                Rects = body["rects"]?.ToString(),
                                Tags = body["tags"]?.ToString(),
                                Extend = body["extend"]?.ToString(),
                                //PersonType = personEnum.GetDescription(),
                                WarnHand = 0,
                               
                            };
                            PersonType personEnum;
                            if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum))
                            {
                                dayEnum = AlarmType.visual_fence;
                            }

                            if (body["extend"] != null)
                            {
                                var extend = JsonConvert.DeserializeObject<JObject>(body["extend"].ToString());
                                model.PersonId = extend?["personId"]?.ToString();
                                model.PersonSetId =extend?["personSetId"]?.ToString();
                                model.ClothId =extend?["clothId"]?.ToString();
                                model.ClothsSetId =extend?["clothsSetId"]?.ToString();
                                model.Gender =extend?["genderScore"]?.ToString();
                                model.TrackId =extend?["trackId"]?.ToString();
                                model.SpeedLevel =extend?["speedLevel"]?.ToString();
                                if (extend["clothSimilarity"] !=null)
                                    model.ClothSimilarity = extend?["clothSimilarity"]?.ParseToFloat();
                                if (extend["count"] != null)
                                    model.Count = extend?["count"]?.ParseToInt();
                                if (extend["duration"] != null)
                                    model.Duration = extend?["duration"]?.ParseToInt();
                                if (extend["faceSimilarity"] != null)
                                    model.FaceSimilarity = extend?["faceSimilarity"]?.ParseToFloat();
                                if (extend["maxAroundTracks"] != null)
                                    model.MaxAroundTracks = extend?["maxAroundTracks"]?.ParseToInt();

                                if (extend["genderScore"] != null)
                                {
                                    if ((float)extend["genderScore"][0] > 0.6)
                                    {
                                        model.Gender = "男性";
                                    }
                                    else if ((float)extend["genderScore"][1] > 0.6)
                                    {
                                        model.Gender = "女性";
                                    }
                                    else if ((float)extend["genderScore"][2] > 0.6)
                                    {
                                        model.Gender = "不确定";
                                    }
                                }
                                if (extend["personType"] != null)
                                {
                                    if (!Enum.TryParse(extend?["personType"]?.ToString(), out personEnum))
                                    {
                                        personEnum = PersonType.unkonwn;
                                    }
                                }
                                else
                                {
                                    personEnum = PersonType.unkonwn;
                                }

                            }
                            else
                            {
                                personEnum = PersonType.unkonwn;
                            }

                            model.AlarmTypeDesc = dayEnum.GetDescription();
                            model.PersonType = personEnum.GetDescription();

                            var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.AlarmId + ".jpg");
                            var steam = await model.SnapshotUrl.GetAsByteArrayAsync();
                            model.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:AlarmImg"]}/{model.AlarmId}.jpg";
                            using (MemoryStream ms = new MemoryStream(steam))
                            {
                                using (Bitmap bmp = new Bitmap(ms))
                                {
                                    using (Graphics g = Graphics.FromImage(bmp))
                                    {
                                        using (Pen pen = new Pen(Color.Red, 3))
                                        {
                                            foreach (var item in body["rects"])
                                            {
                                                Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]);
                                                g.DrawRectangle(pen, rect);
                                            }
                                        }
                                    }
                                    bmp.Save(signImg, ImageFormat.Jpeg);
                                }
                            }
                            Scoped.Create((_, scope) =>
                            {
                                var services = scope.ServiceProvider;
                                var _repository = services.GetService<IWarnInfoService>();
                                _repository.Add(model);
                            });
                        }
                    }
                    else if (json["type"].ToString() == "cmd")
                    {
                        if ((bool)json["success"])
                        {
                            if (json["message"].ToString().Contains("connect success"))
                            {
                                LogHelper.WriteToLog("预警连接成功");
                            }
                            else if (json["message"].ToString().Contains("subscribe success"))
                            {
                                LogHelper.WriteToLog("预警订阅成功");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}");
                    LogHelper.WriteToLog("预警webSocket处理异常");
                    LogHelper.WriteToLog(e, "预警webSocket处理异常");
                }

            }
            else if (result.MessageType == WebSocketMessageType.Close)
            {
                LogHelper.WriteToLog("WebSocket 连接已被服务器关闭");
                break;
            }
        }
        LogHelper.WriteToLog("预警webSocket关闭");
    }
    /// <summary>
    /// 订阅点名事件
    /// </summary>
    /// <returns></returns>
    public async Task SubscriberRoomCall()
    {
        var setting = App.GetOptionsMonitor<AppInfoOptions>();
        var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        var url = GetWebSocketUrl(AuthConstants.SXROOM_CALL, AuthConstants.SXROOM_CAL_Group);
        var subscribeJson = JsonConvert.SerializeObject(new
        {
            token = GetToken(),
            type = "subscribe",
            timestamp,
            payload = new
            {
                topic = AuthConstants.SXROOM_CALL, consumerGroup = AuthConstants.SXROOM_CAL_Group, tags = setting.TenantCode
            }
        });
        ClientWebSocket _webSocket = new ClientWebSocket();
        webScokets.Add(_webSocket);
        await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None);
        //LogHelper.WriteToLog($"点名WebSocket 地址:{url}");
        await _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None);
        byte[] buffer = new byte[1024*8];
        while (_webSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            if (result.MessageType == WebSocketMessageType.Text)
            {
                try
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    //LogHelper.WriteToLog($"收到: {message}");
                    var json = JsonConvert.DeserializeObject<JObject>(message);
                    if (json["type"].ToString() == "msg")
                    {
                        var body = json["body"];
                        if (body != null)
                        {
                            //TODO 发送短信
                            //TxySmsUtil.SendSms(new[] { "" }, new[] { "" });
                            //TODO 由于未知道数据格式暂不写处理
                            if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum))
                            {
                                dayEnum = AlarmType.class_room_call;
                            }

                            if (dayEnum==AlarmType.lie_on_table)
                            {
                                
                            }
                            else
                            {
                                #region 添加预警

                                var ymmodel = new WarnInfoDto
                                {
                                    TenantCode = body["tenantCode"]?.ToString(),
                                    PoiId = body["poiId"]?.ToString(),
                                    AlarmId = body["alarmId"]?.ToString(),
                                    AlarmType = body["alarmType"]?.ToString(),
                                    //AlarmTypeDesc = dayEnum.GetDescription(),
                                    CameraId = body["cameraId"]?.ToString(),
                                    Tick = TimestampToDateTime(body["tick"].ToString()),
                                    SnapshotUrl = body["snapshotUrl"]?.ToString(),
                                    Rects = body["rects"]?.ToString(),
                                    Tags = body["tags"]?.ToString(),
                                    Extend = body["extend"]?.ToString(),
                                    //PersonType = personEnum.GetDescription(),
                                    WarnHand = 0,

                                };
                                PersonType personEnum;

                                if (body["extend"] != null)
                                {
                                    var extend = JsonConvert.DeserializeObject<JObject>(body["extend"].ToString());
                                    ymmodel.PersonId = extend?["personId"]?.ToString();
                                    ymmodel.PersonSetId = extend?["personSetId"]?.ToString();
                                    ymmodel.ClothId = extend?["clothId"]?.ToString();
                                    ymmodel.ClothsSetId = extend?["clothsSetId"]?.ToString();
                                    ymmodel.Gender = extend?["genderScore"]?.ToString();
                                    ymmodel.TrackId = extend?["trackId"]?.ToString();
                                    ymmodel.SpeedLevel = extend?["speedLevel"]?.ToString();
                                    if (extend["clothSimilarity"] != null)
                                        ymmodel.ClothSimilarity = extend?["clothSimilarity"]?.ParseToFloat();
                                    if (extend["count"] != null)
                                        ymmodel.Count = extend?["count"]?.ParseToInt();
                                    if (extend["duration"] != null)
                                        ymmodel.Duration = extend?["duration"]?.ParseToInt();
                                    if (extend["faceSimilarity"] != null)
                                        ymmodel.FaceSimilarity = extend?["faceSimilarity"]?.ParseToFloat();
                                    if (extend["maxAroundTracks"] != null)
                                        ymmodel.MaxAroundTracks = extend?["maxAroundTracks"]?.ParseToInt();

                                    if (extend["genderScore"] != null)
                                    {
                                        if ((float)extend["genderScore"][0] > 0.6)
                                        {
                                            ymmodel.Gender = "男性";
                                        }
                                        else if ((float)extend["genderScore"][1] > 0.6)
                                        {
                                            ymmodel.Gender = "女性";
                                        }
                                        else if ((float)extend["genderScore"][2] > 0.6)
                                        {
                                            ymmodel.Gender = "不确定";
                                        }
                                    }
                                    if (extend["personType"] != null)
                                    {
                                        if (!Enum.TryParse(extend?["personType"]?.ToString(), out personEnum))
                                        {
                                            personEnum = PersonType.unkonwn;
                                        }
                                    }
                                    else
                                    {
                                        personEnum = PersonType.unkonwn;
                                    }

                                }
                                else
                                {
                                    personEnum = PersonType.unkonwn;
                                }

                                ymmodel.AlarmTypeDesc = dayEnum.GetDescription();
                                ymmodel.PersonType = personEnum.GetDescription();

                                var yjsignImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], ymmodel.AlarmId + ".jpg");
                                var yjsteam = await ymmodel.SnapshotUrl.GetAsByteArrayAsync();
                                ymmodel.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:AlarmImg"]}/{ymmodel.AlarmId}.jpg";
                                using (MemoryStream ms = new MemoryStream(yjsteam))
                                {
                                    using (Bitmap bmp = new Bitmap(ms))
                                    {
                                        using (Graphics g = Graphics.FromImage(bmp))
                                        {
                                            using (Pen pen = new Pen(Color.Red, 3))
                                            {
                                                foreach (var item in body["rects"])
                                                {
                                                    Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]);
                                                    g.DrawRectangle(pen, rect);
                                                }
                                            }
                                        }
                                        bmp.Save(yjsignImg, ImageFormat.Jpeg);
                                    }
                                }
                                Scoped.Create((_, scope) =>
                                {
                                    var services = scope.ServiceProvider;
                                    var _repository = services.GetService<IWarnInfoService>();
                                    _repository.Add(ymmodel);
                                });

                                #endregion
                            }
                            #region 添加点名

                            var model = new ClassRoomCallDto
                            {
                                TenantCode = body["tenantCode"]?.ToString(),
                                PoiId = body["poiId"]?.ToString(),
                                TaskId = body["taskId"]?.ToString(),
                                AlarmType = body["alarmType"].ToString(),
                                AlarmTypeDesc = dayEnum.GetDescription(),
                                EventId = body["eventId"]?.ToString(),
                                CameraId = body["cameraId"]?.ToString(),
                                Tick = TimestampToDateTime(body["tick"]?.ToString()),
                                PersonSetId = body["personSetId"]?.ToString(),
                                PersonId = body["personId"]?.ToString(),
                                Similarity = body["similarity"] != null ? (float)body["similarity"] : 0,
                                FaceScore = body["faceScore"] != null ? (float)body["faceScore"] : 0,
                                SnapshotUrl = body["snapshotUrl"]?.ToString(),
                                SnapshotData = body["snapshotData"]?.ToString(),
                                Rects = body["rects"]?.ToString(),
                                Extend = body["extend"]?.ToString(),
                                CreateTime = DateTime.Now,
                                TrackId = body["TrackId"]?.ToString()
                            };
                            var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:RoomCallImg"], model.EventId + ".jpg");
                            var steam = await model.SnapshotUrl.GetAsByteArrayAsync();
                            model.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:RoomCallImg"]}/{model.EventId}.jpg";
                            using (MemoryStream ms = new MemoryStream(steam))
                            {
                                using (Bitmap bmp = new Bitmap(ms))
                                {
                                    using (Graphics g = Graphics.FromImage(bmp))
                                    {
                                        using (Pen pen = new Pen(Color.Red, 3))
                                        {
                                            foreach (var item in body["rects"])
                                            {
                                                Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]);
                                                g.DrawRectangle(pen, rect);
                                            }
                                        }
                                    }
                                    bmp.Save(signImg, ImageFormat.Jpeg);
                                }
                            }
                            Scoped.Create((_, scope) =>
                            {
                                var services = scope.ServiceProvider;
                                var _repository = services.GetService<IClassRoomCallService>();
                                _repository.Add(model);
                            });

                            #endregion
                        }
                    }
                    else if (json["type"].ToString() == "cmd")
                    {
                        if ((bool)json["success"])
                        {
                            if (json["message"].ToString().Contains("connect success"))
                            {
                                LogHelper.WriteToLog("点名连接成功");
                            }
                            else if (json["message"].ToString().Contains("subscribe success"))
                            {
                                LogHelper.WriteToLog("点名订阅成功");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}");
                    LogHelper.WriteToLog("点名webSocket处理异常");
                    LogHelper.WriteToLog(e, "点名webSocket处理异常");
                }
            }
            else if (result.MessageType == WebSocketMessageType.Close)
            {
                LogHelper.WriteToLog("点名WebSocket 连接已被服务器关闭");
                break;
            }
        }
        LogHelper.WriteToLog("点名webSocket已关闭");
    }
    /// <summary>
    /// 订阅无感考勤
    /// </summary>
    /// <returns></returns>
    public async Task SubscriberAttendance()
    {
        var setting = App.GetOptionsMonitor<AppInfoOptions>();
        var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        var url = GetWebSocketUrl(AuthConstants.SXECOLOGY_ATTENDANCE, AuthConstants.SXECOLOGY_ATTENDANCE_Group);
        var subscribeJson = JsonConvert.SerializeObject(new
        {
            token = GetToken(),
            type = "subscribe",
            timestamp,
            payload = new
            {
                topic = AuthConstants.SXECOLOGY_ATTENDANCE,
                consumerGroup = AuthConstants.SXECOLOGY_ATTENDANCE_Group,
                tags = setting.TenantCode
            }
        });
        ClientWebSocket _webSocket = new ClientWebSocket();
        webScokets.Add(_webSocket);
        await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None);
        //LogHelper.WriteToLog($"考勤WebSocket 已连接:{url}");
        await _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None);
        byte[] buffer = new byte[1024 * 8];
        while (_webSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            if (result.MessageType == WebSocketMessageType.Text)
            {
                try
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    //LogHelper.WriteToLog($"收到: {message}");
                    var json = JsonConvert.DeserializeObject<JObject>(message);
                    if (json["type"].ToString() == "msg")
                    {
                        var body = json["body"];
                        if (body != null)
                        {

                            //TODO 发送短信
                            //TxySmsUtil.SendSms(new[] { "" }, new[] { "" });
                            //TODO 由于未知道数据格式暂不写处理
                            var model = new AttendanceDto()
                            {
                                TenantCode = body["tenantCode"]?.ToString(),
                                PoiId = body["poiId"]?.ToString(),
                                EventId = body["eventId"]?.ToString(),
                                CameraId = body["cameraId"]?.ToString(),
                                Tick = TimestampToDateTime(body["tick"]?.ToString()),
                                PersonSetId = body["personSetId"]?.ToString(),
                                PersonId = body["personId"]?.ToString(),
                                Similarity = body["similarity"] != null ? (float)body["similarity"] : 0,
                                FaceScore = body["faceScore"] != null ? (float)body["faceScore"] : 0,
                                SnapshotUrl = body["snapshotUrl"]?.ToString(),
                                SnapshotData = body["snapshotData"]?.ToString(),
                                Rects = body["rects"]?.ToString(),
                                Extend = body["extend"]?.ToString(),
                                CreateTime = DateTime.Now,
                                TrackId = body["trackId"]?.ToString(),
                                IsAuto = true

                            };
                            var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AttendanceImg"], model.EventId + ".jpg");
                            var steam = await model.SnapshotUrl.GetAsByteArrayAsync();
                            model.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:AttendanceImg"]}/{model.EventId}.jpg";
                            using (MemoryStream ms = new MemoryStream(steam))
                            {
                                using (Bitmap bmp = new Bitmap(ms))
                                {
                                    using (Graphics g = Graphics.FromImage(bmp))
                                    {
                                        using (Pen pen = new Pen(Color.Red, 3))
                                        {
                                            foreach (var item in body["rects"])
                                            {
                                                Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]);
                                                g.DrawRectangle(pen, rect);
                                            }
                                        }
                                    }
                                    bmp.Save(signImg, ImageFormat.Jpeg);
                                }
                            }
                            Scoped.Create((_, scope) =>
                            {
                                var services = scope.ServiceProvider;
                                var repository = services.GetService<IAttendanceService>();
                                repository.Add(model);
                            });
                        }
                    }else if (json["type"].ToString()=="cmd")
                    {
                        if ((bool)json["success"])
                        {
                            if (json["message"].ToString().Contains("connect success"))
                            {
                                LogHelper.WriteToLog("考勤连接成功");
                            }else if (json["message"].ToString().Contains("subscribe success"))
                            {
                                LogHelper.WriteToLog("考勤订阅成功");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}");
                    LogHelper.WriteToLog("考勤webSocket处理异常");
                    LogHelper.WriteToLog(e, "考勤webSocket处理异常");
                }
            }
            else if (result.MessageType == WebSocketMessageType.Close)
            {
                LogHelper.WriteToLog("考勤WebSocket 连接已被服务器关闭");
                break;
            }
        }
        LogHelper.WriteToLog("考勤webSocket已关闭");
    }

    private async Task GetWebSocketData(string url, string json)
    {
        ClientWebSocket _webSocket = new ClientWebSocket();
        while (!_cancellationTokenSource.IsCancellationRequested)
        {
            try
            {
                await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None);
                LogHelper.WriteToLog("WebSocket 已连接");
                _isConnected = true;
                //订阅预警消息
                await _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None);

                //_pingTimer = new Timer(async (state) =>
                //{
                //    if (_webSocket.State == WebSocketState.Open)
                //    {
                //        try
                //        {
                //            LogHelper.WriteToLog("发送 ping...");
                //            byte[] emptyPingMessage = Array.Empty<byte>();
                //            await _webSocket.SendAsync(new ArraySegment<byte>(emptyPingMessage), WebSocketMessageType.Binary, true, CancellationToken.None);
                //            //byte[] pingMessage = Encoding.UTF8.GetBytes("pong");
                //            //await _webSocket.SendAsync(new ArraySegment<byte>(pingMessage), WebSocketMessageType.Text, true, CancellationToken.None);
                //        }
                //        catch (Exception ex)
                //        {
                //            LogHelper.WriteToLog($"发送ping失败: {ex.Message}");
                //        }
                //    }
                //}, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));

                await ReceiveLoop(_webSocket);

                _isConnected = false;
                LogHelper.WriteToLog("WebSocket 连接已关闭,正在重连。。。");
            }
            catch (Exception ex)
            {
                LogHelper.WriteToLog($"WebSocket连接失败: {ex.Message}");
            }

            await Task.Delay(GetReconnectInterval());
        }
    }
    private async Task ReceiveLoop(ClientWebSocket _webSocket)
    {
        byte[] buffer = new byte[1024];
        while (_webSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            if (result.MessageType == WebSocketMessageType.Text)
            {
                string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                LogHelper.WriteToLog($"收到: {message}");
                var json= JsonConvert.DeserializeObject<JObject>(message);
                if (json["type"].ToString()=="msg")
                {
                    var body = json["body"];
                    if (body!=null)
                    {
                       
                    }
                }
            }
            else if (result.MessageType == WebSocketMessageType.Close)
            {
                LogHelper.WriteToLog("WebSocket 连接已被服务器关闭");
                break;
            }
        }
    }
    private TimeSpan GetReconnectInterval()
    {
        // You can implement your own logic for calculating reconnect interval, e.g., exponential backoff
        return TimeSpan.FromSeconds(10); // Example: Attempt to reconnect every 10 seconds
    }
    public async Task DisconnectAsync()
    {
        foreach (var clientWebSocket in webScokets.Where(clientWebSocket => clientWebSocket.State == WebSocketState.Open))
        {
            await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
        }
    }
    private string GetWebSocketUrl(string topic, string consumerGroup)
    {
        var serverAddr = "";
        var setting = App.GetOptionsMonitor<AppInfoOptions>();
        var list = $"{setting.SXAPIURL}/emitter/connection/get"
            .SetBody(new
            {
                token = GetToken(),
                topic ,
                consumerGroup,
            })
            .SetContentType("application/json")
            .PostAsAsync<string>().Result;
        var model = JsonConvert.DeserializeObject<JObject>(list);
        if (model["data"]["serverAddr"]!=null)
        {
            serverAddr = model["data"]["serverAddr"].ToString();
        }
        return serverAddr;
    }

    //public async Task<bool> GetData()
    //{
    //    //var setting = App.GetOptionsMonitor<AppInfoOptions>();
    //    //var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
    //    ////订阅预警消息
    //    //var warnUrl = GetWebSocketUrl(AuthConstants.SXALARM, AuthConstants.SXALARM_Grpup);
    //    //GetWebSocketData(warnUrl,
    //    //    JsonConvert.SerializeObject(new
    //    //    {
    //    //        token = GetToken(), type = "subscribe", timestamp,
    //    //        payload = new { topic =  AuthConstants.SXALARM, consumerGroup= AuthConstants.SXALARM_Grpup, tags= setting.TenantCode }
    //    //    }));
    //    //订阅预警更新消息
    //    await SubscribeAlarm();
    //    //订阅点名事件
    //    //await SubscriberRoomCall();
    //    return true;
    //}
    /// <summary>
    /// 时间戳转本时区日期时间
    /// </summary>
    /// <param name="timeStamp"></param>
    /// <returns></returns>
    public static DateTime TimestampToDateTime(string timeStamp)
    {
        DateTimeOffset utcDateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(timeStamp));
        return utcDateTimeOffset.LocalDateTime;
    }

}