using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc;
using NPOI.POIFS.Properties;
using Panda.DynamicWebApi.Attributes;
using System.Collections.Generic;

namespace IRaCIS.Core.Application.Service
{

    /// <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<(GetReadingTableQuestionOutDto, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto)
        {
            var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();
            var formType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.ReadingQuestionCriterionTrialId).Select(x => x.FormType).FirstOrDefaultAsync();
            if (inDto.FormType != null)
            {
                formType = inDto.FormType.Value;
            }
            var tableAnswers = await _readingTableQuestionAnswerRepository
             .ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
           .Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();

            var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();

            var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
            var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
            var result = await GetReadingTableQuestion(new GetReadingTableQuestionOrAnswerInDto()
            {

                TrialReadingCriterionId = inDto.ReadingQuestionCriterionTrialId,
                TaskId = inDto.VisitTaskId,
                TableAnswers = tableAnswers,
                TableAnsweRowInfos = tableAnsweRowInfos,
                OrganInfos = organList,
                QuestionClassify = null,

            });


            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).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.GroupId == item.Id)).ToList();
            var itemChild = _mapper.Map<List<GetSystemReadingQuestionOutDto>>(tableQuestions.Where(x => x.ReadingQuestionId == item.Id).ToList());
            itemChild.ForEach(x =>
            {
                x.Childrens = new List<GetSystemReadingQuestionOutDto>();
                x.GroupName = string.Empty;
                x.ImageCount = 0;
                var relationQuestions= _mapper.Map<List<GetSystemReadingQuestionOutDto>>(tableQuestions.Where(z => (z.DependParentId ?? default(Guid)) == x.Id).ToList());
                relationQuestions.ForEach(y =>
                {
                    y.Childrens = new List<GetSystemReadingQuestionOutDto>();
                    y.GroupName = string.Empty;
                    y.ImageCount = 0;
                    y.LesionType = item.LesionType;
                    y.RelationQuestions = new List<GetSystemReadingQuestionOutDto>();
                });

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