using Furion;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Nirvana.Common;
using Nirvana.Common.Extend;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YBDevice.Entity;

namespace YBDevice.Application.CommonInfo
{
    public class CommonService : ICommonService, ITransient
    {
        private readonly ISqlSugarRepository<YB_Combined> repository;
        private readonly SqlSugarClient dbClient;
        public CommonService(ISqlSugarRepository<YB_Combined> sqlSugarRepository)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
        }
        /// <summary>
        /// 插入或者更新汇总表
        /// </summary>
        /// <returns></returns>
        public async Task InsertOrUpdateCombinedAsync()
        {
            int devcnt = await dbClient.Queryable<YB_Device>().CountAsync();
            int businesscnt = await dbClient.Queryable<YB_Business>().CountAsync();
            int todaydevactinvecnt = await dbClient.Queryable<YB_Device>().Where(x => SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
            if (await dbClient.Queryable<YB_Combined>().AnyAsync(x => x.Id == 1))
            {
                await dbClient.Updateable<YB_Combined>().SetColumns(x => new YB_Combined
                {
                    TotalDevCnt = devcnt,
                    BusinessCnt = businesscnt,
                    TodayDevCnt = todaydevactinvecnt
                }).Where(x => x.Id == 1).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable<YB_Combined>(new YB_Combined
                {
                    TodayDevCnt = todaydevactinvecnt,
                    BusinessCnt = businesscnt,
                    TodayIncome = 0,
                    TodayRegCnt = 0,
                    TodayResultCnt = 0,
                    TotalDevCnt = devcnt,
                    TotalIncome = 0,
                    TotalRegCnt = 0,
                    TotalResultCnt = 0
                }).ExecuteCommandAsync();
            }
        }
        /// <summary>
        /// 添加分配记录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task InsertAllocAsync(YB_DeviceAlloc data)
        {
            data.CreateTime = DateTime.Now;
            data.Id = IDGen.NextID();
            await dbClient.Insertable(data).ExecuteCommandAsync();
        }

        /// <summary>
        /// 添加分配记录
        /// </summary>
        /// <param name="equids">设备列表</param>
        /// <param name="frombusinessid">分配人</param>
        /// <param name="tobusinessid">接收人</param>
        /// <param name="type">类型,1-出货,2-分配,3-回收,4-激活</param>
        /// <returns></returns>
        public async Task InsertAllocAsync(List<int> equids, int frombusinessid, int tobusinessid, DeviceAllocType type)
        {
            List<YB_DeviceAlloc> list = new List<YB_DeviceAlloc>();
            equids.ForEach(x =>
            {
                list.Add(new YB_DeviceAlloc
                {
                    Id = IDGen.NextID(),
                    CreateTime = DateTime.Now,
                    EquId = x,
                    FromBusinessId = frombusinessid,
                    ToBusinessId = tobusinessid,
                    Type = type
                });
            });
            await dbClient.Insertable(list).ExecuteCommandAsync();
        }

        /// <summary>
        /// 更新或者插入指定商户实时数据
        /// </summary>
        /// <param name="BusinessId"></param>
        /// <returns></returns>
        public async Task InsertOrUpdateRealDataAsync(int BusinessId)
        {
            if (BusinessId > 0)
            {
                int todaydevactivecnt = await dbClient.Queryable<YB_Device>().Where(x => x.BusinessId == BusinessId && SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
                int devcnt = await dbClient.Queryable<YB_Device>().Where(x => x.BusinessId == BusinessId).CountAsync();
                int businesscnt = await dbClient.Queryable<YB_Business>().Where(x => x.ParentId == BusinessId).CountAsync();
                if (!await dbClient.Queryable<YB_BusinessRealData>().AnyAsync(x => x.BusinessId == BusinessId))
                {
                    await dbClient.Insertable(new YB_BusinessRealData
                    {
                        BusinessId = BusinessId,
                        Balance = 0,
                        BusinessCount = businesscnt,
                        CreateTime = DateTime.Now,
                        DevCount = devcnt,
                        TodayIncome = 0,
                        TodayResultCnt = 0,
                        TotalIncome = 0,
                        TotalResultCnt = 0,
                        TotalTxAmount = 0,
                        TodayDevCount = todaydevactivecnt,
                        TotalRealCnt = 0,
                        TodayRealCnt = 0
                    }).ExecuteCommandAsync();
                }
                else
                {
                    await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                    {
                        DevCount = devcnt,
                        TodayDevCount = todaydevactivecnt,
                        BusinessCount = businesscnt
                    }).Where(x => x.BusinessId == BusinessId).ExecuteCommandAsync();
                }
            }
        }
        /// <summary>
        /// 更新或者插入指定商户实时数据
        /// </summary>
        /// <param name="BusinessId"></param>
        /// <returns></returns>
        public async Task InsertOrUpdateRealDataAsync(List<int> BusinessId)
        {
            if (BusinessId != null && BusinessId.Count > 0)
            {
                BusinessId = BusinessId.IDistinctList();
                foreach (var item in BusinessId)
                {
                    await InsertOrUpdateRealDataAsync(item);
                }
            }
        }

        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public LoginInfoDto AccessToken(OperatorModel account)
        {
            string accessToken;
            accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>() {
                    {"BusinessId",account.BusinessId},
                    {"BusinessCode",account.BusinessCode},
                    {"UserId",account.UserId},
                    {"RealName",account.RealName},
                    {"RoleId",account.RoleId},
                    {"LoginIPAddress",account.LoginIPAddress},
                    {"LoginTime",account.LoginTime},
                    {"AccountType",account.AccountType},
                    {"IsSuper",account.IsSuper},
                    {"Type",account.Type},
                });
            //获取刷新token
            var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, 43200); // 第二个参数是刷新 token 的有效期（分钟），默认三十天
            return new LoginInfoDto
            {
                RefreshToken = refreshToken,
                Token = accessToken
            };
        }
    }
}
