using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
    public class GeneralCalculateService : BaseService, IGeneralCalculateService
    {

        private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
        private readonly IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository;
        private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
        private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<TumorAssessment> _tumorAssessmentRepository;
        private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;

        public GeneralCalculateService(
            IRepository<ReadingTableQuestionAnswer> readingTableQuestionAnswerRepository,
            IRepository<VisitTask> visitTaskRepository,
            IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
            IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
            IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
            IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
            IRepository<SubjectVisit> subjectVisitRepository,
            IRepository<TumorAssessment> tumorAssessmentRepository,
            IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository
            )
        {
            this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
            this._visitTaskRepository = visitTaskRepository;
            this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
            this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
            this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
            this._readingQuestionTrialRepository = readingQuestionTrialRepository;
            this._subjectVisitRepository = subjectVisitRepository;
            this._tumorAssessmentRepository = tumorAssessmentRepository;
            this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
        }

        /// <summary>
        /// 获取ReadingCalculateDto
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        public async Task<ReadingCalculateDto> GetReadingCalculateDto(Guid visitTaskId)
        {
            var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();

            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).FirstNotNullAsync();
            var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == (visitTask.SourceSubjectVisitId ?? default(Guid))).FirstOrDefaultAsync();

            var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == visitTask.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();


            var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync();

            var baseLinetaskId = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == baseLineVisitId && x.TaskState == TaskState.Effect
            && x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
            && x.ArmEnum == visitTask.ArmEnum).Select(x => x.Id).FirstOrDefaultAsync();

            List<QuestionInfo> questionInfos = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTask.TrialReadingCriterionId).Select(x => new QuestionInfo()
            {
                LesionType = x.LesionType,
                QuestionId = x.Id,
                QuesionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
                QuestionType = x.QuestionType,
                ValueType = x.ValueType,
            }).ToListAsync();

            var questionAnswers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => new
            {
                x.ReadingQuestionTrialId,
                x.Answer
            }).ToListAsync();

            var tableQuestion = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingTableQuestionTrial).Select(x => new TableQuestionInfo()
            {
                Answer = x.Answer,
                AnswerId=x.Id,
                QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
                TableQuestionId = x.TableQuestionId,
                QuestionId = x.QuestionId,
                QuestionType = x.ReadingQuestionTrial.QuestionType,
                RowIndex = x.RowIndex,
                RowId = x.RowId,
            }).ToListAsync();

            foreach (var item in questionInfos)
            {
                item.Answer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;


                var thisItemRowInfo = rowInfoList.Where(x => x.QuestionId == item.QuestionId).ToList();

                var thisItemTableQuestions = tableQuestion.Where(x => x.QuestionId == item.QuestionId).ToList();

                item.TableRowInfoList = thisItemRowInfo.Select(x => new TableRowInfo()
                {
                    RowIndex = x.RowIndex,
                    MeasureData = x.MeasureData,
                    FristAddTaskNum=x.FristAddTaskNum,
                    TableQuestionList = tableQuestion.Where(y => y.QuestionId == item.QuestionId && y.RowId == x.Id).ToList(),

                }).ToList();




            }

            ReadingCalculateDto readingData = new ReadingCalculateDto()
            {
                SubjectId = visitTask.SubjectId,
                TaskBlindName=  visitTask.TaskBlindName,
                VisitTaskId = visitTaskId,
                SubjectVisitId = visitTask.SourceSubjectVisitId!.Value,
                QuestionInfo = questionInfos,
                CriterionId = visitTask.TrialReadingCriterionId,
                TrialId = visitTask.TrialId,
                IsAnalysisCreate = visitTask.IsAnalysisCreate,
                IsSelfAnalysis = visitTask.IsSelfAnalysis,
                IsBaseLine = subjectVisit!.IsBaseLine,
                DoctorUserId = visitTask.DoctorUserId,
                TrialReadingCriterionId = visitTask.TrialReadingCriterionId,
                BaseLineTaskId = baseLinetaskId,
                ArmEnum = visitTask.ArmEnum,
                VisitName = subjectVisit.VisitName,
                BlindName = subjectVisit.BlindName,
                VisitTaskNum = visitTask.VisitTaskNum,
                DigitPlaces= criterionInfo.DigitPlaces??2,
            };

            return readingData;
        }

        /// <summary>
        /// 获取阅片报告任务List
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        public async Task<List<VisitTaskInfo>> GetReadingReportTaskList(Guid visitTaskId)
        {
            var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();

            var taskquery = _visitTaskRepository
              .Where(x => (x.SubjectId == visitTaskInfo.SubjectId && x.TaskState == TaskState.Effect
               && x.IsAnalysisCreate == visitTaskInfo.IsAnalysisCreate
              && x.DoctorUserId == visitTaskInfo.DoctorUserId
              && x.IsSelfAnalysis == visitTaskInfo.IsSelfAnalysis
             && x.VisitTaskNum <= visitTaskInfo.VisitTaskNum
              && x.ArmEnum == visitTaskInfo.ArmEnum
              && x.TrialReadingCriterionId == visitTaskInfo.TrialReadingCriterionId
              && x.ReadingCategory == ReadingCategory.Visit && x.ReadingTaskState == ReadingTaskState.HaveSigned) || x.Id == visitTaskId
            );
            if(visitTaskInfo.ReadingTaskState==ReadingTaskState.HaveSigned)
            {
                taskquery = _visitTaskRepository.Where(x => visitTaskInfo.RelatedVisitTaskIdList.Contains(x.Id)||x.Id==visitTaskInfo.Id);
            }


            var taskInfoList = await taskquery.OrderBy(x => x.VisitTaskNum).Select(x => new VisitTaskInfo()
            {
                BlindName = x.TaskBlindName,
                IsBaseLine = x.SourceSubjectVisit.IsBaseLine,
                VisitTaskId = x.Id,
                TaskName = x.TaskName,
                LatestScanDate= x.SourceSubjectVisit!=null?x.SourceSubjectVisit.LatestScanDate : null,
                VisitTaskNum = x.VisitTaskNum,
                IsCurrentTask = x.Id == visitTaskId,
                 
            }).ToListAsync();

            return taskInfoList;
        }
    }
}