using JetBrains.Annotations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualBasic;
using NPOI.OpenXmlFormats.Wordprocessing;
using Shentun.Peis.Enums;
using Shentun.Peis.Models;
using Shentun.Peis.PatientRegisters;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Account;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
namespace Shentun.Peis.SumSummaryReports
{
    /// 
    /// 总诊台报告
    /// 
    [ApiExplorerSettings(GroupName = "Work")]
    [Authorize]
    public class SumSummaryReportAppService : ApplicationService
    {
        private readonly IRepository _patientRepository;
        private readonly IRepository _registerCheckRepository;
        private readonly IRepository _identityUserRepository;
        private readonly IRepository _itemTypeRepository;
        private readonly IRepository _registerCheckItemRepository;
        private readonly IRepository-  _itemRepository;
        private readonly IRepository _patientRegisterRepository;
        private readonly IRepository _registerCheckAsbitemRepository;
        private readonly IRepository _resultStatusRepository;
        private readonly ISumSummaryReportRepository _sumSummaryReportRepository;
        private readonly CacheService _cacheService;
        private readonly IRepository _registerCheckSummaryRepository;
        private readonly IRepository _asbitemRepository;
        public SumSummaryReportAppService(
            IRepository patientRepository,
            IRepository registerCheckRepository,
            IRepository identityUserRepository,
            IRepository itemTypeRepository,
            IRepository patientRegisterRepository,
            IRepository registerCheckAsbitemRepository,
            ISumSummaryReportRepository sumSummaryReportRepository,
            IRepository resultStatusRepository,
            CacheService cacheService,
            IRepository registerCheckSummaryRepository,
            IRepository asbitemRepository,
            IRepository
-  itemRepository,
            IRepository registerCheckItemRepository)
        {
            this._registerCheckRepository = registerCheckRepository;
            this._identityUserRepository = identityUserRepository;
            this._itemTypeRepository = itemTypeRepository;
            this._patientRegisterRepository = patientRegisterRepository;
            this._registerCheckAsbitemRepository = registerCheckAsbitemRepository;
            this._sumSummaryReportRepository = sumSummaryReportRepository;
            _cacheService = cacheService;
            _resultStatusRepository = resultStatusRepository;
            _registerCheckSummaryRepository = registerCheckSummaryRepository;
            _asbitemRepository = asbitemRepository;
            _itemRepository = itemRepository;
            _registerCheckItemRepository = registerCheckItemRepository;
            _patientRepository = patientRepository;
        }
        /// 
        /// 获取明细结果报告
        /// 
        /// 人员登记ID
        /// 
        [HttpPost("api/app/SumSummaryReport/GetDetailResults")]
        public async Task
> GetDetailResultsAsync(PatientRegisterIdInputDto input)
        {
            List msg = new List();
            var userlist = await _identityUserRepository.GetListAsync();
            var resultStatus = await _resultStatusRepository.GetListAsync();
            var list = (from patient in await _patientRepository.GetQueryableAsync()
                        join patientRegister in await _patientRegisterRepository.GetQueryableAsync()
                        on patient.Id equals patientRegister.PatientId
                        join registerCheck in await _registerCheckRepository.GetQueryableAsync()
                        on patientRegister.Id equals registerCheck.PatientRegisterId
                        join registerCheckAsbitem in await _registerCheckAsbitemRepository.GetQueryableAsync()
                        on registerCheck.Id equals registerCheckAsbitem.RegisterCheckId
                        join registerCheckSummary in await _registerCheckSummaryRepository.GetQueryableAsync()
                        on registerCheck.Id equals registerCheckSummary.RegisterCheckId
                        join asbitem in await _asbitemRepository.GetQueryableAsync()
                        on registerCheckAsbitem.AsbitemId equals asbitem.Id
                        join registerCheckItem in await _registerCheckItemRepository.GetQueryableAsync()
                        on registerCheck.Id equals registerCheckItem.RegisterCheckId
                        join item in await _itemRepository.GetQueryableAsync()
                        on registerCheckItem.ItemId equals item.Id
                        join itemType in await _itemTypeRepository.GetQueryableAsync()
                        on asbitem.ItemTypeId equals itemType.Id
                        where patientRegister.Id == input.PatientRegisterId
                        select new
                        {
                            patient,
                            patientRegister,
                            registerCheck,
                            registerCheckSummary,
                            registerCheckAsbitem,
                            asbitem,
                            registerCheckItem,
                            item,
                            itemType
                        }).AsNoTracking().ToList();
            if (!list.Any())
            {
                return null;
            }
            //获取历次结果
            var histroyList = (from patient in await _patientRepository.GetQueryableAsync()
                               join patientRegister in await _patientRegisterRepository.GetQueryableAsync()
                               on patient.Id equals patientRegister.PatientId
                               join registerCheck in await _registerCheckRepository.GetQueryableAsync()
                               on patientRegister.Id equals registerCheck.PatientRegisterId
                               join registerCheckAsbitem in await _registerCheckAsbitemRepository.GetQueryableAsync()
                               on registerCheck.Id equals registerCheckAsbitem.RegisterCheckId
                               join registerCheckSummary in await _registerCheckSummaryRepository.GetQueryableAsync()
                               on registerCheck.Id equals registerCheckSummary.RegisterCheckId
                               join asbitem in await _asbitemRepository.GetQueryableAsync()
                               on registerCheckAsbitem.AsbitemId equals asbitem.Id
                               join registerCheckItem in await _registerCheckItemRepository.GetQueryableAsync()
                               on registerCheck.Id equals registerCheckItem.RegisterCheckId
                               join item in await _itemRepository.GetQueryableAsync()
                               on registerCheckItem.ItemId equals item.Id
                               join itemType in await _itemTypeRepository.GetQueryableAsync()
                               on asbitem.ItemTypeId equals itemType.Id
                               where patient.Id == list.First().patient.Id
                               && (patientRegister.CompleteFlag == PatientRegisterCompleteFlag.SumCheck || patientRegister.CompleteFlag == PatientRegisterCompleteFlag.Audit)
                               && patientRegister.MedicalTimes < list.First().patientRegister.MedicalTimes
                               select new
                               {
                                   patient,
                                   patientRegister,
                                   registerCheck,
                                   registerCheckSummary,
                                   registerCheckAsbitem,
                                   asbitem,
                                   registerCheckItem,
                                   item,
                                   itemType
                               }).OrderByDescending(o => o.patientRegister.MedicalTimes).ToList();
            //将子项目类别设置为父项目类别
            var itemTypes = await _itemTypeRepository.GetListAsync();
            foreach (var listItem in list)
            {
                var parentItemType = itemTypes.Where(o => o.Id == listItem.itemType.ParentId).FirstOrDefault();
                if (parentItemType != null)
                {
                    listItem.asbitem.DisplayOrder = listItem.itemType.DisplayOrder * 1000 + listItem.asbitem.DisplayOrder;
                    listItem.itemType.DisplayName = parentItemType.DisplayName;
                    listItem.itemType.DisplayOrder = parentItemType.DisplayOrder;
                }
            }
            var detailedResultsList_Asbitems = new List();
            var registerCheckIds = list.OrderBy(o => o.itemType.DisplayOrder)
                .OrderBy(o => o.asbitem.DisplayOrder)
                .Select(o => o.registerCheck.Id).Distinct().ToList();
            foreach (var registerCheckId in registerCheckIds)
            {
                var listItem = list.Where(o => o.registerCheck.Id == registerCheckId).First();
                var detailedResultsList_Asbitem = new SumSummaryReportDetailResultWithAsbitem()
                {
                    ItemTypeName = listItem.itemType.DisplayName,
                    AsbitemName = string.Join(",", list.Where(o => o.registerCheck.Id == registerCheckId)
                            .OrderBy(o => o.itemType.DisplayOrder).OrderBy(o => o.asbitem.DisplayOrder)
                            .Select(o => o.asbitem.DisplayName).Distinct().ToList()),
                    ItemTypeDisplayOrder = listItem.itemType.DisplayOrder,
                    AsbitemDisplayOrder = listItem.asbitem.DisplayOrder,
                    CheckDate = ((DateTime)listItem.registerCheck.CheckDate).Date,
                    CheckDoctorName = EntityHelper.GetCheckDoctorName(listItem.registerCheck.CheckDoctorId, userlist),
                    Items = list.Where(o => o.registerCheck.Id == registerCheckId)
                    .OrderBy(o => o.itemType.DisplayOrder).OrderBy(o => o.asbitem.DisplayOrder).OrderBy(o => o.item.DisplayOrder)
                    .Select(o => new SumSummaryReportDetailResultWithItem()
                    {
                        ItemId = o.registerCheckItem.ItemId,
                        ItemName = o.item.DisplayName,
                        ItemResult = o.registerCheckItem.Result,
                        ReferenceRangeValue = o.registerCheckItem.ReferenceRangeValue,
                        CriticalRangeValue = o.registerCheckItem.CriticalRangeValue,
                        Unit = o.registerCheckItem.Unit,
                        ResultStatusId = o.registerCheckItem.ResultStatusId,
                        ResultStatusName = (resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault() == null) ? "" : resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault().ReportPrompt,
                        ReportFontColor = (resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault() == null) ? 0 : resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault().ReportFontColor,
                        ReportBackgroundColor = (resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault() == null) ? 16777215 : resultStatus.Where(x => x.Id == o.registerCheckItem.ResultStatusId).FirstOrDefault().ReportBackgroundColor,
                    }).Distinct().ToList(),
                    Summarys = list.Where(o => o.registerCheck.Id == registerCheckId)
                               .OrderBy(o=>o.registerCheckSummary.DisplayOrder)
                               .GroupBy(o=>o.registerCheckSummary.Summary)
                               .Select(o=> new SumSummaryReportDetailResultWithSummary(){
                                  Summary = o.FirstOrDefault().registerCheckSummary.Summary })
                                  .ToList(),  
                };
                detailedResultsList_Asbitem.Summarys = detailedResultsList_Asbitem.Summarys.Distinct().ToList();
                foreach (var registerCheckItem in detailedResultsList_Asbitem.Items)
                {
                    var historyRegisterCheckItems = histroyList.GroupBy(o=>o.registerCheckItem)
                         .Select(o => o.First().registerCheckItem )
                         .Where(o => o.ItemId == registerCheckItem.ItemId)
                         .Distinct().ToList();
                    for (var i = 0; i < historyRegisterCheckItems.Count; i++)
                    {
                        if(i== 0)
                        {
                            registerCheckItem.PreviousItemResult = historyRegisterCheckItems[i].Result;
                            registerCheckItem.PreviousReportFontColor = (resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault() == null) ? 0 : resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault().ReportFontColor;
                            registerCheckItem.PreviousReportBackgroundColor = (resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault() == null) ? 16777215 : resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault().ReportBackgroundColor;
                        }
                        else if(i== 1)
                        {
                            registerCheckItem.PreviousTwoItemResult = historyRegisterCheckItems[i].Result;
                            registerCheckItem.PreviousTwoReportFontColor = (resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault() == null) ? 0 : resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault().ReportFontColor;
                            registerCheckItem.PreviousTwoReportBackgroundColor = (resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault() == null) ? 16777215 : resultStatus.Where(x => x.Id == historyRegisterCheckItems[i].ResultStatusId).FirstOrDefault().ReportBackgroundColor;
                        }
                    }
                }
                detailedResultsList_Asbitems.Add(detailedResultsList_Asbitem);
            }
            var grouplist = detailedResultsList_Asbitems.OrderBy(o=>o.ItemTypeDisplayOrder)
                .OrderBy(o=>o.AsbitemDisplayOrder)
                .GroupBy(g => g.ItemTypeName);
            foreach (var g in grouplist)
            {
                var glist = g.ToList();
                var resultlist = new SumSummaryReportDetailResultDto
                {
                    ItemTypeName = glist.FirstOrDefault().ItemTypeName,
                    Asbitems = glist
                };
                msg.Add(resultlist);
            }
            return msg;
        }
        /// 
        /// 获取项目类别对比报告
        /// 
        /// 档案ID(不是档案号)
        /// 
        [HttpGet("api/app/sumsummaryreport/getitemtypecontrastlist")]
        public async Task> GetItemTypeContrastListAsync(Guid PatientId)
        {
            List msg = new List();
            var query = from a in await _patientRegisterRepository.GetQueryableAsync()
                        join b in await _registerCheckRepository.GetQueryableAsync() on a.Id equals b.PatientRegisterId
                        join c in await _registerCheckAsbitemRepository.GetQueryableAsync() on b.Id equals c.RegisterCheckId
                        join d in await _asbitemRepository.GetQueryableAsync() on c.AsbitemId equals d.Id into dd
                        from ad in dd.DefaultIfEmpty()
                        join e in await _itemTypeRepository.GetQueryableAsync() on ad.ItemTypeId equals e.Id
                        join f in await _registerCheckSummaryRepository.GetQueryableAsync() on b.Id equals f.RegisterCheckId into ff
                        from af in ff.DefaultIfEmpty()
                        where a.PatientId == PatientId && a.CompleteFlag != PatientRegisterCompleteFlag.PreRegistration
                        select new
                        {
                            RegisterDate = a.CreationTime,
                            PatientRegisterId = a.Id,
                            ItemTypeName = e.DisplayName,
                            Summary = af != null ? af.Summary : ""
                        };
            var grouplist = query.ToList().GroupBy(g => new { g.PatientRegisterId, g.ItemTypeName });
            foreach (var g in grouplist)
            {
                var glist = g.ToList();
                var resultlist = new ItemTypeContrastListDto
                {
                    ItemTypeName = glist.FirstOrDefault().ItemTypeName,
                    RegisterDate = DataHelper.ConversionDateToString(glist.FirstOrDefault().RegisterDate),
                    Summarys = string.Join("\n", glist.Select(s => s.Summary).ToList())
                };
                msg.Add(resultlist);
            }
            return msg.OrderBy(o => o.ItemTypeName).ThenBy(o => o.RegisterDate).ToList();
        }
        /// 
        /// 获取历次综述
        /// 
        /// 档案ID(不是档案号)
        /// 
        [HttpGet("api/app/sumsummaryreport/gethistoricalreviewlist")]
        public async Task> GetHistoricalReviewListAsync(Guid PatientId)
        {
            List msg = new List();
            var userlist = await _identityUserRepository.GetListAsync();
            var entlist = (await _patientRegisterRepository.GetDbSetAsync())
                 .Include(x => x.SumSummaryHeaders)
                 .ThenInclude(x => x.SumSummaryContents)
                 .Include(x => x.SumSuggestionHeaders)
                 .ThenInclude(x => x.SumSuggestionContents)
                 .Where(m => m.PatientId == PatientId && (m.SumSummaryHeaders.Count > 0 || m.SumSuggestionHeaders.Count > 0)
                 && m.CompleteFlag != PatientRegisterCompleteFlag.PreRegistration)
                 .ToList();
            //以registercheck表为主
            var registercheckList = entlist.Select(s => new HistoricalReviewListDto
            {
                MedicalTimes = s.MedicalTimes,
                SummaryDate = DataHelper.ConversionDateToString(s.SummaryDate),
                SummaryDoctor = _cacheService.GetSurnameAsync(s.SummaryDoctorId).Result,
                SumSuggestions = SetSumSuggestions(s.SumSuggestionHeaders.ToList()),
                SumSummarys = SetSumSummarys(s.SumSummaryHeaders.ToList())
            }).OrderByDescending(o => o.MedicalTimes).ToList();
            return registercheckList;
        }
        /// 
        /// 获取横向对比 左侧组合项目
        /// 
        /// 
        /// 
        [HttpGet("api/app/sumsummaryreport/gethorizontalcomparisonasbitemlist")]
        public async Task> GetHorizontalComparisonAsbitemListAsync(Guid PatientId)
        {
            List entdto = new List();
            var entlist = (await _registerCheckAsbitemRepository.GetDbSetAsync())
            .Include(x => x.Asbitem)
            .Include(x => x.RegisterCheck)
            .Include(x => x.PatientRegister)
            .Where(m => m.PatientRegister.PatientId == PatientId && m.PatientRegister.CompleteFlag != PatientRegisterCompleteFlag.PreRegistration)
            .ToList();
            var grouplist = entlist.GroupBy(o => o.AsbitemId);
            foreach (var g in grouplist)
            {
                //var resultlist = new ItemTypeContrastListDto
                //{
                //    ItemTypeName = glist.FirstOrDefault().ItemTypeName,
                //    RegisterDate = glist.FirstOrDefault().RegisterDate,
                //    Summarys = string.Join("\n", glist.Select(s => s.Summarys).ToList())
                //};
                var glist = g.ToList();
                var ent = new HorizontalComparisonAsbitemListDto
                {
                    AsbitemId = glist.Any() ? glist.FirstOrDefault().AsbitemId : Guid.Empty,
                    AsbitemName = glist.Any() ? glist.FirstOrDefault().Asbitem.DisplayName : "",
                    CompleteFlag = glist.Any() ? glist.OrderByDescending(m => m.CreationTime).FirstOrDefault().RegisterCheck.CompleteFlag : RegisterCheckCompleteFlag.UnChecked
                };
                entdto.Add(ent);
            }
            //var entdto = entlist.Select(s => new HorizontalComparisonAsbitemListDto
            //{
            //    AsbitemId = s.AsbitemId,
            //    AsbitemName = s.Asbitem.DisplayName,
            //    CompleteFlag = s.RegisterChecks.FirstOrDefault(m => m.CreationTime)
            //}).ToList();
            return entdto;
        }
        /// 
        /// 获取横向对比数据
        /// 
        /// 
        /// 
        /// 
        [HttpGet("api/app/sumsummaryreport/gethorizontalcomparisonlist")]
        public async Task> GetHorizontalComparisonListAsync(Guid PatientId, Guid AsbitemId)
        {
            var entlist = await _sumSummaryReportRepository.GetHorizontalComparisonListAsync(PatientId, AsbitemId);
            var entdto = ObjectMapper.Map, List>(entlist);
            return entdto;
        }
        /// 
        /// 生成历次综述医生小结
        /// 
        /// 
        /// 
        private string SetSumSummarys(List SumSummaryHeaders)
        {
            StringBuilder msg = new StringBuilder();
            if (SumSummaryHeaders.Count > 0)
            {
                foreach (var item in SumSummaryHeaders)
                {
                    msg.Append("*  " + item.SummaryTitle + ":" + "
");
                    if (item.SumSummaryContents.Count > 0)
                    {
                        var SumSummaryContents = item.SumSummaryContents.ToList();
                        foreach (var item2 in SumSummaryContents)
                        {
                            msg.Append("(" + SumSummaryContents.IndexOf(item2) + 1 + ")" + item2.SummaryContent + "
");
                        }
                    }
                }
            }
            return msg.ToString();
        }
        /// 
        /// 生成历次综述医生建议
        /// 
        /// 
        /// 
        private string SetSumSuggestions(List SumSuggestionHeaders)
        {
            StringBuilder msg = new StringBuilder();
            if (SumSuggestionHeaders.Count > 0)
            {
                foreach (var item in SumSuggestionHeaders)
                {
                    msg.Append("*  " + item.SuggestionTitle + ":" + "
");
                    if (item.SumSuggestionContents.Count > 0)
                    {
                        var SumSuggestionContents = item.SumSuggestionContents.ToList();
                        foreach (var item2 in SumSuggestionContents)
                        {
                            msg.Append("(" + SumSuggestionContents.IndexOf(item2) + 1 + ")" + item2.SuggestionContent + "
");
                        }
                    }
                }
            }
            return msg.ToString();
        }
    }
}