using DotNetCore.CAP;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Furion.RemoteRequest.Extensions;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Nirvana.Common;
using SqlSugar;
using System;
using System.Text;
using System.Threading.Tasks;
using Waste.Application.ThirdApiInfo;
using Waste.Domain;

namespace Waste.Application.SubscribeInfo
{
    /// <summary>
    /// CAP订阅相关接口
    /// </summary>
    public class SubscribeService : ISubscribeService, ICapSubscribe, ITransient
    {
        private readonly ISqlSugarRepository<W_Device> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IResultService _resultService;
        private readonly ILoggerService _loggerService;

        public SubscribeService(ISqlSugarRepository<W_Device> sqlSugarRepository, IResultService resultService, ILoggerService loggerService)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _resultService = resultService;
            _loggerService = loggerService;
        }

        /// <summary>
        /// 添加记录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.insert")]
        public async Task InsertResultAsync(ResultS2SDto data)
        {
            bool isfrist = false;
            if (data.LastHeartTime.HasValue && data.LastHeartTime.Value.Date != DateTime.Now.Date)
            {
                isfrist = true;
            }
            await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new
            {
                deviceid = data.DeviceId,
                businessid = data.BusinessId,
                resultid = data.ResultId,
                imei = data.imei,
                iccid = data.iccid,
                imsi = data.imsi,
                time = DateTime.Now,
                latitude = data.latitude,
                longitude = data.longtitude,
                sign = data.gslq,
                city = "",
                area = data.trash,
                wastetype = data.wastetype,
                weigth = data.weight,
                isheart = 0,
                tare = data.Tare,
                isfrist = isfrist
            });
        }

        /// <summary>
        /// 更新记录上报结果
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.update")]
        public async Task UpdateStatusAsync(UpdateStatusDto data)
        {
            Guid resultid = Guid.Empty;
            if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
            {
                if (await dbClient.Queryable<W_ResultExt>().AnyAsync(x => x.ResultId == resultid))
                {
                    await dbClient.Updateable<W_ResultExt>().SetColumns(x => new W_ResultExt
                    {
                        Status = data.status
                    }).Where(x => x.ResultId == resultid).ExecuteCommandAsync();
                }
                else
                {
                    var insertdata = new W_ResultExt
                    {
                        Id = IDGen.NextID(),
                        Status = data.status,
                        CreateTime = DateTime.Now,
                        ResultId = resultid
                    };
                    await dbClient.Insertable(insertdata).ExecuteCommandAsync();
                }
            }
        }

        /// <summary>
        /// 心跳数据上报
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("device.service.postheart")]
        public async Task UpdateHeartInfoAsync(DevHeartRequestDto data)
        {
            var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
            if (device == null)
            {
                return;
            }
            if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == device.Id))
            {
                //更新设备心跳信息
                if (data.Latitude == 0 || data.Longitude == 0)
                {
                    await dbClient.Updateable<W_DeviceData>()
                        .SetColumns(x => new W_DeviceData
                        {
                            LastBeatTime = DateTime.Now
                        })
                        .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
                }
                else
                {
                    string longitude = data.Longitude.ToString();
                    string Latitude = data.Latitude.ToString();
                    await dbClient.Updateable<W_DeviceData>()
                     .SetColumns(x => new W_DeviceData
                     {
                         LastBeatTime = DateTime.Now,
                         Longitude = longitude,
                         Latitude = Latitude
                     })
                     .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
                }
            }
            else
            {
                var insertdata = new W_DeviceData
                {
                    DeviceId = device.Id,
                    Sign = data.GSLQ.ToString(),
                    IMSI = data.IMSI,
                    ICCID = data.ICCID,
                    IMEI = data.IMEI,
                    LastBeatTime = DateTime.Now,
                    Latitude = data.Latitude.ToString(),
                    Longitude = data.Longitude.ToString()
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 更新设备开机信息
        /// </summary>
        /// <param name="deviceid"></param>
        /// <returns></returns>
        [CapSubscribe("device.service.update")]
        public async Task UpdateRegInfoAsync(Guid deviceid)
        {
            //更新开机时间
            if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == deviceid))
            {
                await dbClient.Updateable<W_DeviceData>()
                         .SetColumns(x => new W_DeviceData
                         {
                             LastStartTime = DateTime.Now
                         })
                         .Where(x => x.DeviceId == deviceid).ExecuteCommandAsync();
            }
            else
            {
                var insertdata = new W_DeviceData
                {
                    DeviceId = deviceid,
                    Sign = "",
                    IMSI = "",
                    ICCID = "",
                    IMEI = "",
                    Latitude = "0",
                    Longitude = "0",
                    LastStartTime = DateTime.Now
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 更新设备版本信息
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("device.service.updatever")]
        public async Task UpdateVersionAsync(DeviceVerS2SDto data)
        {
            var deivce = await dbClient.Queryable<W_Device>().Select(x => new W_Device { Id = x.Id }).FirstAsync(x => x.Ecode == data.ecode);
            if (deivce == null)
            {
                return;
            }
            //更新版本号
            if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == deivce.Id))
            {
                await dbClient.Updateable<W_DeviceData>()
                         .SetColumns(x => new W_DeviceData
                         {
                             Version = data.ver
                         })
                         .Where(x => x.DeviceId == deivce.Id).ExecuteCommandAsync();
            }
            else
            {
                var insertdata = new W_DeviceData
                {
                    DeviceId = deivce.Id,
                    Sign = "",
                    IMSI = "",
                    ICCID = "",
                    IMEI = "",
                    Latitude = "0",
                    Longitude = "0",
                    LastStartTime = DateTime.Now,
                    Version = data.ver
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 4G模块传输的数据增加测量记录
        /// </summary>
        /// <param name="myPackage"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.insert4g")]
        public async Task Insert4GResultAsync(nMyPackage myPackage)
        {
            await _resultService.InsertResultBy4GAsync(myPackage);
        }

        /// <summary>
        /// 测试,4G模块传输的数据增加测量记录
        /// </summary>
        /// <param name="myPackage"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.testinsert4g")]
        public void Test(nMyPackage myPackage)
        {
            var msg = JsonConvert.SerializeObject(myPackage);
            _loggerService.AddLogger(msg, 1);
        }

        /// <summary>
        /// 第三方推送设备消息
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("third.service.sendmessage")]
        public async Task SeedThirdMessageAsync(SendThirdMessageSubscriDto data)
        {
            string errmsg = string.Empty;
            var senddata = data.Adapt<SendMessageToThirdS2CDto>();
            var devicedata = await dbClient.Queryable<W_DeviceData>().Where(x => x.DeviceId == data.DeviceId).Select(x => new W_DeviceData
            {
                LastBeatTime = x.LastBeatTime
            }).FirstAsync();
            senddata.BeatTime = devicedata == null ? 0 : devicedata.LastBeatTime.GetTimeStamp();
            var response = await data.Url
                .SetBody(senddata, "application/json", Encoding.UTF8)
                .OnException((res, errors) =>
                {
                    errmsg = errors;
                }).PostAsync();
            if (errmsg != string.Empty)
            {
                _loggerService.AddLogger($"第三方设备消息发送失败,内容:{data.ToJson()},返回:{errmsg}", 1);
            }
            var returnstr = await response.Content.ReadAsStringAsync();
            if (!response.IsSuccessStatusCode)
            {
                _loggerService.AddLogger($"第三方设备消息发送失败,内容:{data.ToJson()},返回:{returnstr}", 1);
            }
            if (returnstr.ToLower() != "success")
            {
                _loggerService.AddLogger($"第三方设备消息发送失败,内容:{data.ToJson()},返回:{returnstr}", 1);
            }
            _loggerService.AddLogger($"第三方设备消息发送成功,内容:{data.ToJson()},返回:{returnstr}", 3);
        }

        /// <summary>
        /// A8 4G模块传输的数据增加测量记录
        /// </summary>
        /// <param name="myPackage"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.inserta84g")]
        public async void InsertA84GResultAsync(A8MyPackage myPackage)
        {
            //_loggerService.AddLogger($"A8记录,内容:{myPackage.ToJson()}", 1);
            //await _resultService.InsertResultByA84GAsync(myPackage);

            await Scoped.Create(async (_, scope) =>
             {
                 var services = scope.ServiceProvider;
                 var mresultrep = services.GetService<ISqlSugarRepository<W_MeasureResult>>();
                 //如果uuid不为空,并且以存在记录,则忽略
                 if (!myPackage.IsHeart && !myPackage.UUID.IsEmpty() && await mresultrep
                         .Where(x => x.CreatedTime > DateTime.Now.AddMinutes(-1) && x.DataHash == myPackage.DataHash)//1分钟内不能重复
                         .AnyAsync())
                 {
                     return;
                 }
                 var _resultService = services.GetService<IResultService>();
                 await _resultService.InsertResultByA84GAsync(myPackage);
             });
        }
    }
}