using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Application.Contracts;
using Panda.DynamicWebApi.Attributes;

namespace IRaCIS.Application.Services
{

    /// <summary>
    /// 问题
    /// </summary>
    public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService
    {
        #region 获取项目已确认的标准
        /// <summary>
        /// 获取项目已确认的标准
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialConfirmCriterionListOutDto>> GetTrialConfirmCriterionList(GetConfirmCriterionInDto inDto)
        {
            var result = await _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterion.IsConfirm)
                .WhereIf(inDto.VisitTaskId != null, t => t.Id == inDto.VisitTaskId)
               .Select(x => new GetTrialConfirmCriterionListOutDto()
               {
                   ReadingQuestionCriterionTrialId = x.TrialReadingCriterion.Id,
                   ReadingQuestionCriterionTrialName = x.TrialReadingCriterion.CriterionName
               }).Distinct().ToListAsync();
            return result;
        }
        #endregion

        #region 获取项目的阅片问题
        /// <summary>
        /// 获取项目的阅片问题ECRF预览
        /// </summary>
        /// <remarks>
        /// SinglePage  单页
        /// 
        /// MultiPage   多页
        /// 
        /// PublicPage  公共
        /// </remarks>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(GetTrialReadingQuestionPageDto, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto)
        {
            if (inDto.VisitTaskId != null)
            {
                //await AddDefaultValueToTask(inDto.VisitTaskId.Value);
            }
          
            var result = new GetTrialReadingQuestionPageDto();
            var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();


            var qusetionList = await GetReadingAnswerView(inDto.ReadingQuestionCriterionTrialId, inDto.VisitTaskId);

            var formType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.ReadingQuestionCriterionTrialId).Select(x => x.FormType).FirstOrDefaultAsync();
            var groupList = new List<GetTrialReadingQuestionOutDto>();

            var qusetionIds = qusetionList.Select(x => x.Id).ToList();
            var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => qusetionIds.Contains(x.ReadingQuestionId))
                .ProjectTo<TableQuestionDataInfo>(_mapper.ConfigurationProvider,x=>new {

                    isEn_Us=_userInfo.IsEn_Us

                }).OrderBy(x => x.ShowOrder).ToListAsync();
            if (inDto.FormType != null)
            {
                formType = inDto.FormType.Value;
            }

            if (formType == FormType.MultiplePage)
            {
                qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId != null).ToList();
                var readingCriterionPageIds = qusetionList.OrderBy(x => x.PageShowOrder).Select(x => x.ReadingCriterionPageId).Distinct().ToList();
                foreach (var item in readingCriterionPageIds)
                {
                    var newPageQusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == item).ToList();
                    var firstData = newPageQusetionList.FirstOrDefault();
                    var page = new GetTrialReadingQuestionOutDto()
                    {
                        PageName = firstData.PageName,
                        IsPage = true,
                        IsPublicPage = firstData.IsPublicPage,
                    };

                    var pageGroupList = newPageQusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
                    pageGroupList.ForEach(x =>
                    {
                        this.FindChildQuestion(x, newPageQusetionList, tableQuestionList);
                    });

                    page.Childrens = pageGroupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count() == 0)).ToList();
                    groupList.Add(page);
                }

                result.PublicPage = groupList.Where(x => x.IsPublicPage.Value).ToList();
                result.MultiPage = groupList.Where(x => !x.IsPublicPage.Value).ToList();
            }
            else
            {
                qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == null).ToList();

                groupList = qusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupId==null)).ToList();
                groupList.ForEach(x =>
                {
                    this.FindChildQuestion(x, qusetionList, tableQuestionList);
                });

                groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count() == 0)).ToList();

                result.SinglePage = groupList;


            }


            return (result, new
            {
                readingTaskState = readingTaskState,
                FormType = formType

            });
        }

        /// <summary>
        /// 项目配置的阅片问题(不包含表格问题) 以及配置的分页 和任务对应的答案 一维表   --   非dicom 阅片
        /// </summary>
        /// <param name="readingQuestionCriterionTrialId"></param>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task<List<GetTrialReadingQuestionOutDto>> GetReadingAnswerView(Guid readingQuestionCriterionTrialId, Guid? visitTaskId)
        {
            var query = from data in _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == readingQuestionCriterionTrialId)

                        join page in _readingCriterionPageRepository.AsQueryable() on data.ReadingCriterionPageId ?? default(Guid) equals page.Id into pageTemp
                        from leftpage in pageTemp.DefaultIfEmpty()

                        join questionAnswer in _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId) on data.Id equals questionAnswer.ReadingQuestionTrialId into questionAnswerTemp
                        from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty()
                        select new GetTrialReadingQuestionOutDto()
                        {

                            Id = data.Id,
                            ReadingQuestionCriterionTrialId = data.ReadingQuestionCriterionTrialId,
                            TrialId = data.TrialId,
                            Type = data.Type,
                            ParentTriggerValue = data.ParentTriggerValue,
                            GroupName = data.GroupName.LanguageName(data.GroupEnName, _userInfo.IsEn_Us),
                            QuestionName = data.QuestionName.LanguageName(data.QuestionEnName, _userInfo.IsEn_Us),
                            IsRequired = data.IsRequired,
                            ShowQuestion = data.ShowQuestion,
                            LesionType = data.LesionType,
                            QuestionGenre = data.QuestionGenre,
                            DictionaryCode = data.DictionaryCode,
                            GroupId=data.GroupId,
                            ShowOrder = data.ShowOrder,
                            RelevanceId = data.RelevanceId,
                            IsShowInDicom = data.IsShowInDicom,
                            MaxQuestionCount = data.MaxQuestionCount,
                            RelevanceValue = data.RelevanceValue,
                            ImageCount = data.ImageCount,
                            ParentId = data.ParentId,
                            TypeValue = data.TypeValue,
                            Answer = leftquestionAnswer.Answer,
                            ReadingCriterionPageId = data.ReadingCriterionPageId,
                            PageName = leftpage.PageName,
                            PageShowOrder = leftpage.ShowOrder,
                            IsPublicPage = leftpage.IsPublicPage,
                            DefaultValue = data.DefaultValue,
                        };

            var qusetionList = await query.Where(x => x.ShowQuestion != ShowQuestion.Hide).OrderBy(x => x.ShowOrder).ToListAsync();

            qusetionList.ForEach(x =>
            {
                x.Answer = x.Answer.IsNullOrEmpty() ? x.DefaultValue : x.Answer;
            });

            return qusetionList;
        }


        /// <summary>
        /// 找子问题
        /// </summary>
        /// <param name="item"></param>
        /// <param name="questionlists"></param>
        /// <param name="tableQuestions"></param>
        [NonDynamicMethod]
        public void FindChildQuestion(GetTrialReadingQuestionOutDto item, List<GetTrialReadingQuestionOutDto> questionlists, List<TableQuestionDataInfo> tableQuestions)
        {
            item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupId == item.Id)).ToList();


            item.Childrens.AddRange(tableQuestions.Where(x => x.ReadingQuestionId == item.Id).Select(x => new GetTrialReadingQuestionOutDto
            {
                Childrens = new List<GetTrialReadingQuestionOutDto>(),
                ShowOrder = x.ShowOrder,
                GroupName = string.Empty,
                Id = x.Id,
                Type = x.Type,
                DictionaryCode = x.DictionaryCode,
                TableQuestionType = x.TableQuestionType,
                DependParentId = x.DependParentId,
                IsDepend = x.IsDepend,
                QuestionMark = x.QuestionMark,
                QuestionGenre = x.QuestionGenre,
                TypeValue = x.TypeValue,
                RelevanceId = x.RelevanceId,
                IsRequired = x.IsRequired,
                RelevanceValue = x.RelevanceValue,
                ImageCount = 0,
                ParentId = item.Id,
                DataTableColumn = x.DataTableColumn,
                LesionType = item.LesionType,
                QuestionName = x.QuestionName,
                RelationQuestions = tableQuestions.Where(z => (z.DependParentId ?? default(Guid)) == x.Id).Select(x => new GetTrialReadingQuestionOutDto
                {
                    Childrens = new List<GetTrialReadingQuestionOutDto>(),
                    ShowOrder = x.ShowOrder,
                    GroupName = string.Empty,
                    Id = x.Id,
                    Type = x.Type,
                    QuestionGenre = x.QuestionGenre,
                    TableQuestionType = x.TableQuestionType,
                    DependParentId = x.DependParentId,
                    DictionaryCode = x.DictionaryCode,
                    IsDepend = x.IsDepend,
                    QuestionMark = x.QuestionMark,
                    TypeValue = x.TypeValue,
                    RelevanceId = x.RelevanceId,
                    RelevanceValue = x.RelevanceValue,
                    ImageCount = 0,
                    ParentId = item.Id,
                    DataTableColumn = x.DataTableColumn,
                    LesionType = item.LesionType,
                    QuestionName = x.QuestionName,
                    RelationQuestions = new List<GetTrialReadingQuestionOutDto>(),
                    Remark = x.Remark,

                }).ToList(),
                Remark = x.Remark,

            }));
            if (item.Childrens != null && item.Childrens.Count != 0)
            {
                item.Childrens.ForEach(x =>
                {
                    this.FindChildQuestion(x, questionlists, tableQuestions);
                });
            }
        }

        #endregion

        #region 获取系统的阅片问题

        /// <summary>
        /// 获取系统的阅片问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetSystemReadingQuestionPageDto> GetSystemReadingQuestion(GetSystemReadingQuestionInDto inDto)
        {
            var result = new GetSystemReadingQuestionPageDto();
            var qusetionList = await _readingQuestionSystem.Where(x => x.ReadingQuestionCriterionSystemId == inDto.Id)
                         .ProjectTo<GetSystemReadingQuestionOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();


            var questionIds = qusetionList.Select(x => x.Id).ToList();
            var tableQuestionList = await _readingTableQuestionSystemRepository.Where(x => questionIds.Contains(x.ReadingQuestionId))
                 .ProjectTo<TableQuestionDataInfo>(_mapper.ConfigurationProvider,new {
                     isEn_Us=_userInfo.IsEn_Us,
                 }).OrderBy(x => x.ShowOrder).ToListAsync();

            var groupList = new List<GetSystemReadingQuestionOutDto>();

            //qusetionList = qusetionList.Where(x => x.ParentId == null).ToList();

            groupList = qusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
            groupList.ForEach(x =>
            {
                this.FindSystemChildQuestion(x, qusetionList, tableQuestionList);
            });

            groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count() == 0)).ToList();

            result.SinglePage = groupList;


            return result;
        }


        /// <summary>
        /// 获取系统
        /// </summary>
        /// <param name="item"></param>
        /// <param name="questionlists"></param>
        /// <param name="tableQuestions"></param>
        public void FindSystemChildQuestion(GetSystemReadingQuestionOutDto item, List<GetSystemReadingQuestionOutDto> questionlists, List<TableQuestionDataInfo> tableQuestions)
        {
            item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupName == item.GroupName)).ToList();

            item.Childrens.AddRange(tableQuestions.Where(x => x.ReadingQuestionId == item.Id).Select(x => new GetSystemReadingQuestionOutDto
            {
                Childrens = new List<GetSystemReadingQuestionOutDto>(),
                ShowOrder = x.ShowOrder,
                GroupName = string.Empty,
               
                Id = x.Id,
                Type = x.Type,
                DictionaryCode = x.DictionaryCode,
                TableQuestionType = x.TableQuestionType,
                DependParentId = x.DependParentId,
                IsDepend = x.IsDepend,
                QuestionMark = x.QuestionMark,
                TypeValue = x.TypeValue,
                RelevanceId = x.RelevanceId,
                IsRequired = x.IsRequired,
                RelevanceValue = x.RelevanceValue,
                ImageCount = 0,
                ParentId = item.Id,
                DataTableColumn = x.DataTableColumn,
                LesionType = item.LesionType,
                QuestionName = x.QuestionName,
                RelationQuestions = tableQuestions.Where(z => (z.DependParentId ?? default(Guid)) == x.Id).Select(x => new GetSystemReadingQuestionOutDto
                {
                    Childrens = new List<GetSystemReadingQuestionOutDto>(),
                    ShowOrder = x.ShowOrder,
                    GroupName = string.Empty,
                    Id = x.Id,
                    DictionaryCode = x.DictionaryCode,
                    Type = x.Type,
                    TableQuestionType = x.TableQuestionType,
                    DependParentId = x.DependParentId,
                    IsDepend = x.IsDepend,
                    QuestionMark = x.QuestionMark,
                    TypeValue = x.TypeValue,
                    RelevanceId = x.RelevanceId,
                    RelevanceValue = x.RelevanceValue,
                    ImageCount = 0,
                    ParentId = item.Id,
                    DataTableColumn = x.DataTableColumn,
                    LesionType = item.LesionType,
                    QuestionName = x.QuestionName,
                    RelationQuestions = new List<GetSystemReadingQuestionOutDto>(),
                    Remark = x.Remark,

                }).ToList(),
                Remark = x.Remark,

            }));

            if (item.Childrens != null && item.Childrens.Count != 0)
            {
                item.Childrens.ForEach(x =>
                {
                    this.FindSystemChildQuestion(x, questionlists, tableQuestions);
                });
            }
        }
        #endregion
    }
}