using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Mapster;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.Entity;
using YBDevice.Entity.ViewModel;

namespace YBDevice.NApi.Application.ChildBody
{
    /// <summary>
    /// 儿童中医体质管理
    /// </summary>
    public class ChildBodyService : BaseService, IChildBodyService, ITransient
    {
        private readonly ISqlSugarRepository<YB_ChildBodyQA> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IDistributedIDGenerator _idGen;
        public ChildBodyService(ISqlSugarRepository<YB_ChildBodyQA> sqlSugarRepository, IDistributedIDGenerator distributedIDGenerator)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _idGen = distributedIDGenerator;
        }
        /// <summary>
        /// 获取已经计算的结果
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetInfoAsync(ChildBodyInfoC2SDto input)
        {
            var result = await dbClient.Queryable<YB_UserChildBody>().Where(x => x.FamilyId == input.FamilyId).ToListAsync();
            //获取结果
            if (result != null && result.Count > 0)
            {
                var data = await GetBodyTypeAsync(result, input.FamilyId);
                return new ResultInfo(ResultState.SUCCESS, "计算成功", data);
            }
            else
            {
                return new ResultInfo(ResultState.FAIL, "抱歉,体质评估失败");
            }
        }
        /// <summary>
        /// 体质结果
        /// </summary>
        /// <param name="result"></param>
        /// <param name="familyid">家庭成员ID</param>
        /// <returns></returns>
        private async Task<ChildBodySubmitResultData> GetBodyTypeAsync(List<YB_UserChildBody> result, int familyid)
        {
            var family = await dbClient.Queryable<YB_Family>().Where(x => x.Id == familyid).Select(x => new YB_Family
            {
                Birthday = x.Birthday
            }).FirstAsync();
            var month = family != null ? family.Birthday.ToDMonth() : 0;
            ChildBodySubmitResultData returndata = new ChildBodySubmitResultData()
            {
                list = new List<ChildBodySubmitResult>(),
                ReferList = new List<string> {
                    "本文部分摘自《健康儿童中医体质辨识方法的研究》作者/王晓鸣，王徐静，林子良,《中华中医药学刊》"
                }
            };
            //如果小于6岁
            if (month <= 12 * 6 * 1.0)
            {
                returndata.ReferList.Add("《0 - 6岁儿童常见中医体质辨识》，作者 / 潘佩光，徐俐平，周俊亮，王欣，田慧");
            }

            // 如果是生机旺盛质>=21，其他6项小于12分,此项得分＜21且其他6项大于12分（否）
            var sjwsdata = result.Where(x => x.Type == ChildBodyTypeEnum.SJWSZ).FirstOrDefault();
            string bodytype = string.Empty;
            string bodytype1 = string.Empty;
            bool hasqx = false; //是否有倾向
            bool haszc = false; //是否有是
            var allresult = await dbClient.Queryable<YB_ChildBodyDetail>()
                .ToListAsync();
            //如果是生机旺盛质 >= 21，其他6项<=12分
            if (sjwsdata != null && result.Where(x => x.Type != ChildBodyTypeEnum.SJWSZ && x.Score <= 12).Count() == 6 && sjwsdata.Score >= 21)
            {
                bodytype = $"您是{EnumHelper.GetEnumTitle(sjwsdata.Type)},";
                var data = allresult.Where(x => x.Type == ChildBodyTypeEnum.SJWSZ).Adapt<ChildBodySubmitResult>();
                data.Result = ChildBodyTypeResult.Yes;
                returndata.list.Add(data);
            }
            else
            {
                bodytype = "您是";
            }
            returndata.list = new List<ChildBodySubmitResult>();
            foreach (var item in result)
            {
                if (item.Type != ChildBodyTypeEnum.SJWSZ)
                {
                    string title = EnumHelper.GetEnumTitle(item.Type);
                    var data = allresult.Where(x => x.Type == item.Type).FirstOrDefault().Adapt<ChildBodySubmitResult>();
                    if (item.Score >= 17)
                    {
                        bodytype += $"{title},";
                        data.Result = ChildBodyTypeResult.Yes;
                        returndata.list.Add(data);
                        haszc = true;
                    }
                    else if (item.Score > 12 && item.Score < 17)
                    {
                        bodytype1 += hasqx ? $"{title}," : $"有{title},";
                        hasqx = true;
                        data.Result = ChildBodyTypeResult.MayBe;
                        returndata.list.Add(data);
                    }
                }
            }
            if (returndata.list == null || returndata.list.Count == 0)
            {
                returndata.BodyType = "您的体质情况很健康";
            }
            else
            {
                if (!string.IsNullOrEmpty(bodytype) && haszc)
                {
                    returndata.BodyType = hasqx ? $"{bodytype}{bodytype1.Substring(0, bodytype1.Length - 1) + "倾向"}" : $"{ bodytype.Substring(0, bodytype.Length - 1)}";
                }
                else
                {
                    returndata.BodyType = $"您{bodytype1.Substring(0, bodytype1.Length - 1)}";
                }
            }
            return returndata;
        }
        /// <summary>
        /// 问答列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetListAsync(ChildBodyListC2SDto input)
        {
            if (input.IsRestart == 1)
            {
                await dbClient.Deleteable<YB_UserChildBody>().Where(x => x.FamilyId == input.FamilyId).ExecuteCommandAsync();
            }
            var list = await dbClient.Queryable<YB_ChildBodyQA>()
                .Where(x => x.SameType == ChildBodyTypeEnum.UnKnown)
                .OrderBy(x => x.Type, OrderByType.Asc)
                .Select(x => new YB_ChildBodyQA
                {
                    Id = x.Id,
                    Type = x.Type,
                    Content = x.Content,
                    SomeValue = x.SomeValue,
                    AlWaysValue = x.AlWaysValue,
                    LittleValue = x.LittleValue,
                    NoneValue = x.NoneValue,
                    OftenValue = x.OftenValue
                }).ToListAsync();
            var returnlist = new List<ChildBodyListS2CDto>();
            foreach (var item in list)
            {
                if (!returnlist.Any(x => x.Id == item.Type))
                {
                    returnlist.Add(new ChildBodyListS2CDto
                    {
                        Id = item.Type,
                        Name = EnumHelper.GetEnumTitle(item.Type),
                        qalist = list.Where(x => x.Type == item.Type).Select(x => new ChildBodyListS2SDto
                        {
                            AlWaysValue = x.AlWaysValue,
                            SomeValue = x.SomeValue,
                            Title = x.Content,
                            LittleValue = x.LittleValue,
                            NoneValue = x.NoneValue,
                            OftenValue = x.OftenValue,
                            Id = x.Id
                        }).ToList()
                    });
                }
            }
            return new ResultInfo(ResultState.SUCCESS, "success", returnlist);
        }
        /// <summary>
        /// 根据分数计算倾向结果
        /// </summary>
        /// <param name="score">分数</param>
        /// <param name="type">类型</param>
        /// <returns></returns>
        private ChildBodyTypeResult GetResult(int score, ChildBodyTypeEnum type)
            => (score, type) switch
            {
                ( >= 17, ChildBodyTypeEnum.PXZ) or
                ( >= 17, ChildBodyTypeEnum.JZZ) or
                ( >= 17, ChildBodyTypeEnum.RZZ) or
                ( >= 17, ChildBodyTypeEnum.XHPWZ) or
                ( >= 17, ChildBodyTypeEnum.SZZ) or
                ( >= 17, ChildBodyTypeEnum.TBZ)
                => ChildBodyTypeResult.Yes,
                ( > 12 and < 17, ChildBodyTypeEnum.PXZ) or
                ( > 12 and < 17, ChildBodyTypeEnum.JZZ) or
                ( > 12 and < 17, ChildBodyTypeEnum.RZZ) or
                ( > 12 and < 17, ChildBodyTypeEnum.XHPWZ) or
                ( > 12 and < 17, ChildBodyTypeEnum.SZZ) or
                ( > 12 and < 17, ChildBodyTypeEnum.TBZ)
                => ChildBodyTypeResult.MayBe,
                _ => ChildBodyTypeResult.No
            };
        /// <summary>
        /// 结果计算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetResultInfoAsync(ChildBodySumitC2SDto data)
        {
            var insertlist = new List<YB_UserChildBody>();
            var nowtime = DateTime.Now;

            // 获取所有的存在同类型的问题
            var allsameqa = await dbClient.Queryable<YB_ChildBodyQA>()
                .Where(x => x.SameType != ChildBodyTypeEnum.UnKnown)
                .Select(x => new YB_ChildBodyQA
                {
                    Id = x.Id,
                    Type = x.Type,
                    SameId = x.SameId,
                    SameType = x.SameType
                }).ToListAsync();
            foreach (var item1 in allsameqa)
            {
                var samedata = data.data.Where(x => x.id == item1.SameType).FirstOrDefault();
                if (samedata != null)
                {
                    var tempdata = samedata.list.Where(x => item1.SameId == x.Id).FirstOrDefault();
                    if (tempdata != null)
                    {
                        // 同类型插入
                        data.data.ForEach(x =>
                        {
                            if (x.id == item1.Type)
                            {
                                x.list.Add(new ChildBodySubmitItemS2SDto
                                {
                                    Id = item1.Id,
                                    Score = tempdata.Score
                                });
                            }
                        });
                    }
                }
            }
            foreach (var item in data.data)
            {
                if (item.id != ChildBodyTypeEnum.SJWSZ)
                {
                    var insertdata = new YB_UserChildBody
                    {
                        Id = _idGen.Create().ToGuid(),
                        CreateTime = nowtime,
                        Score = item.list != null ? item.list.Sum(e => e.Score) : 0,
                        FamilyId = data.FamilyId,
                        Type = item.id,
                        UserId = authInfo.UserId
                    };
                    insertdata.Result = GetResult(insertdata.Score, item.id);
                    insertlist.Add(insertdata);
                }
            }
            var sjwsdata = data.data.Where(x => x.id == ChildBodyTypeEnum.SJWSZ).FirstOrDefault();
            if (sjwsdata != null)
            {
                if (insertlist.Where(x => x.Score <= 12).Count() == 6 && sjwsdata.list.Sum(x => x.Score) >= 21)
                {
                    insertlist.Add(new YB_UserChildBody
                    {
                        Id = _idGen.Create().ToGuid(),
                        CreateTime = nowtime,
                        Score = sjwsdata.list != null ? sjwsdata.list.Sum(e => e.Score) : 0,
                        FamilyId = data.FamilyId,
                        Type = sjwsdata.id,
                        UserId = authInfo.UserId,
                        Result = ChildBodyTypeResult.Yes
                    });
                }
                else
                {
                    insertlist.Add(new YB_UserChildBody
                    {
                        Id = _idGen.Create().ToGuid(),
                        CreateTime = nowtime,
                        Score = sjwsdata.list != null ? sjwsdata.list.Sum(e => e.Score) : 0,
                        FamilyId = data.FamilyId,
                        Type = sjwsdata.id,
                        UserId = authInfo.UserId,
                        Result = ChildBodyTypeResult.No
                    });
                }
            }
            if (insertlist.Count > 0)
            {
                if (await dbClient.Queryable<YB_UserChildBody>().AnyAsync(x => x.FamilyId == data.FamilyId))
                {
                    await dbClient.Deleteable<YB_UserChildBody>().Where(x => x.FamilyId == data.FamilyId).ExecuteCommandAsync();
                }
                await dbClient.Insertable(insertlist).ExecuteCommandAsync();
                var returndata = await GetBodyTypeAsync(insertlist, data.FamilyId);
                return new ResultInfo(ResultState.SUCCESS, "计算成功", returndata);
            }
            return new ResultInfo(ResultState.FAIL, "抱歉,体质评估失败");
        }
    }
}
