using DotNetCore.CAP;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Nirvana.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YBDevice.Core;
using YBDevice.Entity;
using System.Linq;
using YBDevice.CommonService.DevTypeInfo;

namespace YBDevice.NApi.Application.SubscriberInfo
{
    /// <summary>
    /// CAP订阅相关接口
    /// </summary>
    public class SubscriberService : ISubscriberService, ICapSubscribe, ITransient
    {
        private readonly ILoggerService _loggerService;
        private readonly ISqlSugarRepository<YB_nMeasureResult> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IDeviceTypeService _deviceTypeService;
        public SubscriberService(ISqlSugarRepository<YB_nMeasureResult> sqlSugarRepository, ILoggerService loggerService, IDeviceTypeService deviceTypeService)
        {
            _loggerService = loggerService;
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _deviceTypeService = deviceTypeService;
        }
        /// <summary>
        /// 添加用户使用过的设备类型
        /// </summary>
        /// <param name="data"></param>
        [CapSubscribe("reguser.service.insertreguserdevtype")]
        public async Task InsertRegUserDevTypeAsync(RegUserDevTypeS2SDto data)
        {
            if (!await dbClient.Queryable<YB_UserEqu>().AnyAsync(x => data.DevType == x.DevType && x.UserId == data.UserId))
            {
                var insertdata = new YB_UserEqu
                {
                    Id = IDGen.NextID(),
                    CreateTime = DateTime.Now,
                    DevType = data.DevType,
                    UserId = data.UserId
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
        }
        /// <summary>
        /// 更新粉丝数据
        /// </summary>
        /// <param name="userinfo"></param>
        /// <returns></returns>
        [CapSubscribe("fans.service.update")]
        public async Task UpdateFansData(YB_WXFans userinfo)
        {
            if (await dbClient.Queryable<YB_WXFans>().AnyAsync(x => x.FansId == userinfo.FansId))
            {
                await dbClient.Updateable<YB_WXFans>().SetColumns(x => new YB_WXFans
                {
                    HeadImgUrl = userinfo.HeadImgUrl,
                    NickName = userinfo.NickName,
                    Sex = userinfo.Sex,
                    City = userinfo.City,
                    Country = userinfo.Country,
                    Province = userinfo.Province
                }).Where(x => x.Id == userinfo.Id).ExecuteCommandAsync();
            }
            else
            {
                var fansdata = new YB_WXFans
                {
                    Id = userinfo.Id,
                    Sex = userinfo.Sex,
                    City = userinfo.City,
                    Country = userinfo.Country,
                    CreateTime = DateTime.Now,
                    FansId = userinfo.FansId,
                    FromType = 1,
                    HeadImgUrl = userinfo.HeadImgUrl,
                    Language = "",
                    NickName = userinfo.NickName,
                    OldOpenId = userinfo.OldOpenId,
                    Province = userinfo.Province
                };
                await dbClient.Insertable(fansdata).ExecuteCommandAsync();
            }
        }
        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="message"></param>
        [CapSubscribe("system.service.inserterrorlogger")]
        public void InsertErrorLogger(string message)
        {
            _loggerService.AddLogger(message);
        }
        /// <summary>
        /// 更新实时数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.updaterealdata")]
        public async Task UpdateRealData(UpdateRealDataS2SDtO data)
        {
            var device = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Id == data.DevId);
            //如果用户认领
            if (data.IsUserTake)
            {
                var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == data.familyid);
                var month = family.Birthday.ToMonth();
                //更新家庭成员的最新体重
                await dbClient.Updateable<YB_Family>().SetColumns(x => new YB_Family
                {
                    Weight = data.weight,
                    Height = data.height,
                    LastHeartTime = DateTime.Now
                }).Where(x => x.Id == data.familyid).ExecuteCommandAsync();
                //更新家庭成员统计数据
                if (family.LastHeartTime.HasValue)
                {
                    await dbClient.Updateable<YB_FamilyData>().SetColumns(x => new YB_FamilyData
                    {
                        LastHeight = data.height,
                        LastWeight = data.weight,
                        LastResultTime = data.CreateTime,
                        TotalCount = x.TotalCount + 1,
                        TodayCount = x.TodayCount + 1,
                        LastTimeWeight = x.LastWeight - data.weight,
                        LastTimeHeight = x.LastHeight - data.height
                    }).Where(x => x.FamilyId == data.familyid).ExecuteCommandAsync();
                }
                else
                {
                    await dbClient.Updateable<YB_FamilyData>().SetColumns(x => new YB_FamilyData
                    {
                        LastHeight = data.height,
                        LastWeight = data.weight,
                        LastResultTime = data.CreateTime,
                        TotalCount = x.TotalCount + 1,
                        TodayCount = x.TodayCount + 1,
                        LastTimeWeight = 0,
                        LastTimeHeight = 0,
                        FirstResultTime = data.CreateTime,
                        FirstHeight = data.height,
                        FirstWeight = data.weight
                    }).Where(x => x.FamilyId == data.familyid).ExecuteCommandAsync();
                }
                //更新家庭成员数据
                List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(device.Type);
                if (await dbClient.Queryable<YB_FamilyRealData>().AnyAsync(x => x.FamilyId == data.familyid && x.DevType == device.Type))
                {
                    await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                    {
                        LastHeight = data.height,
                        LastWeight = data.weight,
                        LastResultTime = data.CreateTime,
                        TotalCount = x.TotalCount + 1,
                        TodayCount = x.TodayCount + 1,
                        LastTimeHeight = x.LastHeight - data.height,
                        LastTimeWeight = x.LastWeight - data.weight
                    }).Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                }
                else
                {
                    var realdata = new YB_FamilyRealData
                    {
                        FamilyId = data.familyid,
                        FirstHeight = data.height,
                        FirstResultTime = data.CreateTime,
                        DevType = device.Type,
                        CreateTime = DateTime.Now,
                        FirstWeight = data.weight,
                        Id = IDGen.NextID(),
                        LastHeight = data.height,
                        LastResultTime = data.CreateTime,
                        LastTimeHeight = 0,
                        LastTimeWeight = 0,
                        LastWeight = data.weight,
                        TodayCount = 1,
                        TotalCount = 1,
                        UserId = family.UserId
                    };
                    await dbClient.Insertable(realdata).ExecuteCommandAsync();
                }
                //添加用户使用过的设备类型
                if (!await dbClient.Queryable<YB_UserEqu>().AnyAsync(x => device.Type == x.DevType && x.UserId == data.UserId))
                {
                    var insertdata = new YB_UserEqu
                    {
                        Id = IDGen.NextID(),
                        CreateTime = DateTime.Now,
                        DevType = device.Type,
                        UserId = data.UserId
                    };
                    await dbClient.Insertable(insertdata).ExecuteCommandAsync();
                }
            }
            //更新设备测量时间
            await dbClient.Updateable<YB_Device>().SetColumns(x => new YB_Device
            {
                LastHeartTime = DateTime.Now
            }).Where(x => x.Id == device.Id).ExecuteCommandAsync();

            //设备今天是否活跃
            int activecnt = (!device.LastHeartTime.HasValue || device.LastHeartTime.Value.Date != DateTime.Now.Date) ? 1 : 0;
            //更新合计统计
            if (await dbClient.Queryable<YB_Combined>().AnyAsync())
            {
                await dbClient.Updateable<YB_Combined>().SetColumns(x => new YB_Combined
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt,
                    TodayDevCnt = x.TodayDevCnt + activecnt
                }).Where(x => x.Id == 1).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_Combined
                {
                    Id = 1,
                    BusinessCnt = 0,
                    TodayDevCnt = 1,
                    TodayIncome = 0,
                    TodayRegCnt = 0,
                    TotalDevCnt = 0,
                    TodayResultCnt = 1,
                    TotalIncome = 0,
                    TotalRegCnt = 0,
                    TotalResultCnt = 1
                }).ExecuteCommandAsync();
            }
            //更新设备统计
            if (await dbClient.Queryable<YB_EquRealData>().AnyAsync(x => x.EquId == device.Id && x.BusinessId == device.BusinessId))
            {
                await dbClient.Updateable<YB_EquRealData>().SetColumns(x => new YB_EquRealData
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt + 1
                }).Where(x => x.EquId == device.Id && x.BusinessId == device.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_EquRealData
                {
                    EquId = device.Id,
                    BusinessId = device.BusinessId,
                    CreateTime = DateTime.Now,
                    TodayInCome = 0,
                    TodayRealCnt = 0,
                    TodayResultCnt = 1,
                    TotalInCome = 0,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1
                }).ExecuteCommandAsync();
            }
            //更新客户统计
            if (await dbClient.Queryable<YB_BusinessRealData>().AnyAsync(x => x.BusinessId == device.BusinessId))
            {
                await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt + 1,
                    TodayDevCount = x.TodayDevCount + activecnt
                }).Where(x => x.BusinessId == device.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_BusinessRealData
                {
                    BusinessId = device.BusinessId,
                    CreateTime = DateTime.Now,
                    TodayRealCnt = 0,
                    TodayResultCnt = 1,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1,
                    Balance = 0,
                    BusinessCount = 0,
                    DevCount = 0,
                    TodayDevCount = 1,
                    TodayIncome = 0,
                    TotalIncome = 0,
                    TotalTxAmount = 0
                }).ExecuteCommandAsync();
            }
        }
        /// <summary>
        /// 添加通知日志
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [CapSubscribe("system.service.insertnoticelogger")]
        public async Task InsertNoticeLoggerAsync(YB_NoticeLogger message)
        {
            var data = new YB_NoticeLogger
            {
                Ip = Net.Ip,
                CreateTime = DateTime.Now,
                FromInfo = message.FromInfo.ToStr(),
                Info = message.Info.ToStr(),
                UA = message.UA.ToStr(),
                UserInfo = message.UserInfo.ToStr(),
                Id = message.Id
            };
            await dbClient.Insertable(data).ExecuteCommandAsync();
        }
    }
}
