using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infra.EFCore.Common;
using MassTransit;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
namespace IRaCIS.Core.Application.Service
{
    /// 
    /// 医学审核问题
    /// 	
    [ ApiExplorerSettings(GroupName = "Reading")]
	public class ReadingMedicineQuestionService: BaseService, IReadingMedicineQuestionService
	{
	    private readonly IRepository _readingMedicineTrialQuestionRepository;
        private readonly IRepository _readingQuestionCriterionTrialRepository;
        private readonly IRepository _trialRepository;
        private readonly IRepository _readingMedicineSystemQuestionRepository;
        public ReadingMedicineQuestionService(
			IRepository readingMedicineTrialQuestionRepository,
			IRepository readingQuestionCriterionTrial,
			IRepository trialRepository,
			IRepository readingMedicineSystemQuestionRepository
			)
		{
            this._readingMedicineTrialQuestionRepository = readingMedicineTrialQuestionRepository;
            this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrial;
            this._trialRepository = trialRepository;
            this._readingMedicineSystemQuestionRepository = readingMedicineSystemQuestionRepository;
        }
		#region 系统   
		/// 
		/// 获取系统的医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task> GetReadingMedicineSystemQuestionList(ReadingMedicineSystemQuestionQuery inDto)
		{
			//避免前端遍历 
			var criterionEnum = inDto.TrialReadingCriterionId != null ? _readingQuestionCriterionTrialRepository.Where(t => t.Id == inDto.TrialReadingCriterionId).Select(t => t.CriterionType).FirstOrDefault(): CriterionType.NoCriterion;
			var query = _readingMedicineSystemQuestionRepository.AsQueryable()
				  .WhereIf(!inDto.TypeValue.IsNullOrEmpty(), x => x.TypeValue.Contains(inDto.TypeValue))
				  .WhereIf(!inDto.ParentTriggerValue.IsNullOrEmpty(), x => x.ParentTriggerValue.Contains(inDto.ParentTriggerValue))
				  .WhereIf(!inDto.QuestionName.IsNullOrEmpty(), x => x.QuestionName.Contains(inDto.QuestionName) )
				  .WhereIf(!inDto.Type.IsNullOrEmpty(), x => x.Type.Contains(inDto.Type))
				  .WhereIf(inDto.ReadingCategory != null, x => x.ReadingCategory == inDto.ReadingCategory)
				  .WhereIf(inDto.CurrentCriterionType!=null,x=>x.CriterionTypeEnum==null||x.CriterionTypeEnum==inDto.CurrentCriterionType)
				  .WhereIf(inDto.CriterionTypeEnum != null, x => x.CriterionTypeEnum==inDto.CriterionTypeEnum)
				  .WhereIf(inDto.TrialReadingCriterionId != null, x => x.CriterionTypeEnum== criterionEnum || x.IsGeneral==true)
				  .WhereIf(inDto.IsGeneral != null, x => x.IsGeneral == inDto.IsGeneral)
				.WhereIf(inDto.LanguageType != null, x => x.LanguageType == inDto.LanguageType.Value)
				  .ProjectTo(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder);
			return await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "LanguageType desc", "ShowOrder asc" });
		}
		/// 
		/// 获取系统的其他医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task> GetReadingMedicineSystemOtherQuestion(GetReadingMedicineSystemOtherQuestionInDto inDto)
		{
			var types = new List()
			{
				"select","radio"
			};
			var questionList = await _readingMedicineSystemQuestionRepository
				.Where(x => types.Contains(x.Type))
				.WhereIf(inDto.Id != null, x => x.Id != inDto.Id && x.ParentId != inDto.Id)
				.WhereIf(inDto.ShowOrder != null, x => x.ShowOrder < inDto.ShowOrder)
					.WhereIf(inDto.ReadingCategory != null, x => x.ReadingCategory == inDto.ReadingCategory)
				.Select(x => new GetReadingMedicineTrialOtherQuestionOutDto()
				{
					Id = x.Id,
					QuestionName = x.QuestionName,
					LanguageType =x.LanguageType,
					TypeValue = x.TypeValue,
					ReadingCategory = x.ReadingCategory,
				}).ToListAsync();
			return questionList;
		}
		/// 
		/// 新增或修改系统医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task AddOrUpdateReadingMedicineSystemQuestion(ReadingMedicineSystemQuestionAddOrEdit inDto)
		{
			var existsQuery = _readingMedicineSystemQuestionRepository
			   .WhereIf(inDto.Id != null, x => x.Id != inDto.Id)
			   .Where(x => x.ShowOrder == inDto.ShowOrder);
			if (await existsQuery.AnyAsync())
			{
                //---当前问题序号存在重复
				return ResponseOutput.NotOk(_localizer["ReadingMed_QNumDup"]);
			}
			//inDto.CriterionEnumStr = $"|{String.Join('|', inDto.CriterionEnumList)}|";
			var entity = await _readingMedicineSystemQuestionRepository.InsertOrUpdateAsync(inDto);
			await _readingMedicineSystemQuestionRepository.SaveChangesAsync();
			return ResponseOutput.Ok(entity.Id.ToString());
		}
		/// 
		/// 删除系统的医学审核问题
		/// 
		/// 
		/// 
		[HttpDelete("{id:guid}")]
		public async Task DeleteReadingMedicineSystemQuestion(Guid id)
		{
			if (await _readingMedicineSystemQuestionRepository.AnyAsync(x => x.ParentId == id))
			{
                //---此问题存在子问题,请先删除子问题
				return ResponseOutput.NotOk(_localizer["ReadingMed_HasSubQ"]);
			}
			var success = await _readingMedicineSystemQuestionRepository.DeleteFromQueryAsync(t => t.Id == id);
			var result = await _readingMedicineSystemQuestionRepository.SaveChangesAsync();
			return ResponseOutput.Result(result);
		}
		#endregion
		  #region 项目   
		/// 获取项目的医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task<(PageOutput, object)> GetReadingMedicineTrialQuestionList(ReadingMedicineTrialQuestionQuery inDto)
		{
			var query = _readingMedicineTrialQuestionRepository.AsQueryable()
				   .Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
				   .WhereIf(!inDto.TypeValue.IsNullOrEmpty(), x => x.TypeValue.Contains(inDto.TypeValue))
				   .WhereIf(!inDto.ParentTriggerValue.IsNullOrEmpty(), x => x.ParentTriggerValue.Contains(inDto.ParentTriggerValue))
				   .WhereIf(!inDto.QuestionName.IsNullOrEmpty(), x => x.QuestionName.Contains(inDto.QuestionName))
				   .WhereIf(!inDto.Type.IsNullOrEmpty(), x => x.Type.Contains(inDto.Type))
				   	.WhereIf(inDto.ReadingCategory != null, x => x.ReadingCategory == inDto.ReadingCategory)
					 	.WhereIf(inDto.LanguageType != null, x => x.LanguageType == inDto.LanguageType)
				   .ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(x=>x.LanguageType).ThenBy(x => x.ShowOrder);
			var isConfirmMedicineQuestion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.IsConfirmMedicineQuestion).FirstOrDefaultAsync();
			var questionList = await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, inDto.SortField, inDto.Asc);
			return (questionList, new
			{
				IsConfirmMedicineQuestion = isConfirmMedicineQuestion,
				//QuestionCount = questionList.Count(),
			});
		}
		/// 
		/// 获取项目的其他医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task> GetReadingMedicineTrialOtherQuestion(GetReadingMedicineTrialOtherQuestionInDto inDto)
		{
			var types = new List()
			{
				"select","radio"
			};
			var questionList = await _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
				.Where(x => types.Contains(x.Type))
				.WhereIf(inDto.Id != null, x => x.Id != inDto.Id && x.ParentId != inDto.Id)
				.WhereIf(inDto.ShowOrder != null, x => x.ShowOrder < inDto.ShowOrder)
					.WhereIf(inDto.ReadingCategory != null, x => x.ReadingCategory == inDto.ReadingCategory)
				.Select(x => new GetReadingMedicineTrialOtherQuestionOutDto()
				{
					Id = x.Id,
					QuestionName = x.QuestionName,
					LanguageType=x.LanguageType,
					TypeValue = x.TypeValue,
					ReadingCategory = x.ReadingCategory,
				}).ToListAsync();
			return questionList;
		}
		/// 
		/// 
		/// 获取预览问题信息
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task> GetMedicineQuestionPreview(GetMedicineQuestionPreviewInDto inDto)
		{
			var trialQuestionList = await _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
					.WhereIf(inDto.ReadingCategory != null, x => x.ReadingCategory == inDto.ReadingCategory)
					  .ProjectTo(_mapper.ConfigurationProvider, new
					  {
						  isEn_Us = _userInfo.IsEn_Us
					  })
				      .OrderBy(x => x.ShowOrder).ToListAsync();
			List readingQuestionList = trialQuestionList.Where(x => x.ParentId == null).ToList();
			readingQuestionList.ForEach(x =>
			{
				FindChildQuestion(x, trialQuestionList);
			});
			return readingQuestionList;
		}
		/// 
		/// 新增或修改项目医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		[TypeFilter(typeof(TrialResourceFilter))]
		public async Task AddOrUpdateReadingMedicineTrialQuestion(ReadingMedicineTrialQuestionAddOrEdit inDto)
		{
			var existsQuery = _readingMedicineTrialQuestionRepository
		   .WhereIf(inDto.Id != null, x => x.Id != inDto.Id)
		   .Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
		   .Where(x => x.ShowOrder == inDto.ShowOrder);
			if (await existsQuery.AnyAsync())
			{
                //---当前问题序号存在重复
				return ResponseOutput.NotOk(_localizer["ReadingMed_QNumDup"]);
			}
			var entity = await _readingMedicineTrialQuestionRepository.InsertOrUpdateAsync(inDto);
			await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
			return ResponseOutput.Ok(entity.Id.ToString());
		}
		/// 
		/// 删除项目的医学审核问题
		/// 
		/// 
		/// 
		[HttpPost]
		[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
		public async Task DeleteReadingMedicineTrialQuestion(DeleteReadingMedicineTrialQuestion inDto)
		{
			if (await _readingMedicineTrialQuestionRepository.AnyAsync(x => x.ParentId == inDto.Id))
			{
                //---此问题存在子问题,请先删除子问题
				return ResponseOutput.NotOk(_localizer["ReadingMed_HasSubQ"]);
			}
			var success = await _readingMedicineTrialQuestionRepository.DeleteFromQueryAsync(t => t.Id == inDto.Id);
			var result = await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
			return ResponseOutput.Result(result);
		}
		#endregion
		#region 项目 医学审核问题  验证  确认  
		/// 
		/// 验证医学审核问题
		/// 
		/// 
		/// 
		/// 
		public async Task VerifyReadingMedicineQuestion(ConfirmReadingMedicineQuestionInDto inDto)
		{
			var readingMedicineQuestionList = await _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
				.Select(x => new TrialQuestion()
				{
					Id = x.Id,
					ReadingCategory = x.ReadingCategory,
					ParentShowOrder = (int?)x.ParentQuestion.ShowOrder,
					ShowOrder = x.ShowOrder,
				}).ToListAsync();
			if (readingMedicineQuestionList.Count == 0)
			{
                //---当前未添加医学审核问题。请先添加医学审核问题,再进行确认。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_NoMedQ"]);
			}
			if (readingMedicineQuestionList.Count() != readingMedicineQuestionList.Select(t => t.ShowOrder).Distinct().Count())
			{
                //---影像医学审核问题显示序号不能重复。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_MedQNumDup"]);
			}
			if (readingMedicineQuestionList.Where(t => t.ParentShowOrder != null).Any(t => t.ParentShowOrder > t.ShowOrder))
			{
                //---父问题的显示序号要比子问题的显示序号小,请确认。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_ParentNumSmall"]);
			}
			var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => new
			{
				x.IsGlobalReading,
				x.IsOncologyReading,
				x.IsArbitrationReading,
			}).FirstNotNullAsync();
            if (!readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Visit))
            {
            
                throw new BusinessValidationFailedException(_localizer["ReadingMed_VisitQNotConfig"]);
            }
            if (criterionInfo.IsGlobalReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Global))
			{
                //---当前标准启用了全局阅片,但未配置全局医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_GlobalQNotConfig"]);
			}
			if (criterionInfo.IsArbitrationReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Judge))
			{
                //---当前标准启用了仲裁阅片,但未配置仲裁医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_ArbitrateQNotConfig"]);
			}
			if (criterionInfo.IsOncologyReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Oncology))
			{
                //---当前标准启用了肿瘤学阅片,但未配置肿瘤学医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_TumorQNotConfig"]);
			}
			return ResponseOutput.Ok();
		}
		/// 
		/// 确认医学审核问题
		/// 
		/// 
		public async Task ConfirmReadingMedicineQuestion(ConfirmReadingMedicineQuestionInDto inDto)
		{
			var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => new
			{
				x.IsGlobalReading,
				x.IsOncologyReading,
				x.IsArbitrationReading,
			}).FirstNotNullAsync();
			var readingMedicineQuestionList = await _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId)
				.Select(x => new TrialQuestion()
				{
					Id = x.Id,
					ReadingCategory = x.ReadingCategory,
					ParentShowOrder = (int?)x.ParentQuestion.ShowOrder,
					ShowOrder = x.ShowOrder,
				}).ToListAsync();
			if (readingMedicineQuestionList.Count == 0)
			{
                //---当前未添加医学审核问题。请先添加医学审核问题,再进行确认。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_NoMedQ"]);
			}
			if (readingMedicineQuestionList.Count() != readingMedicineQuestionList.Select(t => t.ShowOrder).Distinct().Count())
			{
                //---影像医学审核问题显示序号不能重复。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_MedQNumDup"]);
			}
			if (readingMedicineQuestionList.Where(t => t.ParentShowOrder != null).Any(t => t.ParentShowOrder > t.ShowOrder))
			{
                //---父问题的显示序号要比子问题的显示序号小,请确认。
				throw new BusinessValidationFailedException(_localizer["ReadingMed_ParentNumSmall"]);
			}
			var trialInfo = await _trialRepository.Where(x => x.Id == inDto.TrialId).FirstNotNullAsync();
			if (criterionInfo.IsGlobalReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Global))
			{
                //---当前标准启用了全局阅片,但未配置全局医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_GlobalQNotConfig"]);
			}
			if (criterionInfo.IsArbitrationReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Judge))
			{
                //---当前标准启用了仲裁阅片,但未配置仲裁医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_ArbitrateQNotConfig"]);
			}
			if (criterionInfo.IsOncologyReading && !readingMedicineQuestionList.Any(x => x.ReadingCategory == ReadingCategory.Oncology))
			{
                //---当前标准启用了肿瘤学阅片,但未配置肿瘤学医学审核问题
				throw new BusinessValidationFailedException(_localizer["ReadingMed_TumorQNotConfig"]);
			}
			await _readingMedicineTrialQuestionRepository.BatchUpdateNoTrackingAsync(x => x.TrialId == inDto.TrialId, x => new ReadingMedicineTrialQuestion()
			{
				IsConfirm = true
			});
			await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
			{
				IsConfirmMedicineQuestion = true
			});
			var result = await _trialRepository.SaveChangesAsync();
			return ResponseOutput.Result(result);
		}
		#endregion
		private void FindChildQuestion(GetMedicineQuestionPreviewOutDto trialReadingQuestion, List questionlists)
		{
			trialReadingQuestion.Childrens = questionlists.Where(x => x.ParentId == trialReadingQuestion.Id).ToList();
			if (trialReadingQuestion.Childrens != null && trialReadingQuestion.Childrens.Count != 0)
			{
				trialReadingQuestion.Childrens.ForEach(x =>
				{
					this.FindChildQuestion(x, questionlists);
				});
			}
		}
		/// 
		/// 从系统里面选择问题添加到项目里面
		/// 
		/// 
		/// 
		[HttpPost]
		public async Task AddTrialDataFromSystem(AddTrialDataFromSystemInDto inDto)
		{
			// 直接写??
			var systemList = await _readingMedicineSystemQuestionRepository.Where(x => inDto.SystemQuestionIds.Contains(x.Id)).ToListAsync();
			var maxOrder = await _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId&&x.TrialReadingCriterionId==inDto.TrialReadingCriterionId).OrderByDescending(x => x.ShowOrder).Select(x => x.ShowOrder).FirstOrDefaultAsync();
				
		   var needList= systemList.Select(x => new TrialDataFromSystem()
				{
					Id = NewId.NextGuid(),
					ShowOrder = x.ShowOrder,
					IsEnable = x.IsEnable,
					LanguageType = x.LanguageType,
					IsRequired = x.IsRequired,
					QuestionName = x.QuestionName,
					TrialReadingCriterionId=inDto.TrialReadingCriterionId,
					Type = x.Type,
					ParentId=x.ParentId,
					SystemQuestionId=x.Id,
					ReadingCategory=x.ReadingCategory,
					TypeValue = x.TypeValue,
					TrialId=inDto.TrialId,
				}).ToList();
			needList.ForEach(x => {
				maxOrder++;
				x.ShowOrder = maxOrder;
			});
			foreach (var item in needList.Where(x => x.ParentId != null))
			{
				var parent = needList.Where(x => x.SystemQuestionId == item.ParentId).FirstOrDefault();
				if (parent == null)
				{
					item.ParentId = null;
					item.ParentTriggerValue = String.Empty;
				}
				else
				{
					item.ParentId = parent.Id;
				}
			}
			await _readingMedicineTrialQuestionRepository.AddRangeAsync(needList);
			 var result = await _readingMedicineTrialQuestionRepository.SaveChangesAsync();
			 return ResponseOutput.Result(result);
		}
    }
}