using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Application.Service.Reading.Interface;
using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Triggers
{
    /// 
    ///  处理  访视  1、提交状态 2、执行状态   3、最早最晚 拍片日期
    /// 
    public class SubjectVisitScanDateTrigger(
         IRepository _subjectVisitRepository,
         IClinicalAnswerService _iClinicalAnswerService,
         IRepository _dicomSeriesRepository,
         IRepository _noneDicomStudyRepository
         ) : IAfterSaveTrigger, IAfterSaveTrigger, IAfterSaveTrigger
    {
        //注意删除不能用扩展方法,必须用EF跟踪的实体  否则不能取到  SubjectVisitId
        public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken)
        {
            var subjectVisitId = context.Entity.SubjectVisitId;
            if (context.ChangeType == ChangeType.Added || context.ChangeType == ChangeType.Modified)
            {
                await UpdateSubjectVisitImageDateAsync(context.Entity.SubjectVisitId);
                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
            }
            if (context.ChangeType == ChangeType.Deleted)
            {
                await UpdateSubjectVisitImageDateAsync(context.Entity.SubjectVisitId);
                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
            }
        }
        public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken)
        {
            var subjectVisitId = context.Entity.SubjectVisitId;
            if (context.ChangeType == ChangeType.Added)
            {
                await UpdateSubjectVisitImageDateAsync(subjectVisitId);
                var studyId = context.Entity.Id;
                //处理Modality
                var seriesModalityList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(u => u.Modality).Distinct();
                string ModaliyStr = string.Join('、', seriesModalityList.ToList());
                context.Entity.Modalities = ModaliyStr;
                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
                //添加检查级别临床数据
                // 检查类型  ModalityForEdit
                // 检查模态  Modalities
                var modalities = context.Entity.Modalities;
                List modalitieTypess = new List() { "PT、CT", "CT、PT", "PET-CT" };
                if (modalitieTypess.Contains(modalities))
                {
                    await _iClinicalAnswerService.AddStudyClinical(new Service.Reading.Dto.AddStudyClinicalInDto()
                    {
                        StudyId = studyId,
                    });
                }
            }
            if (context.ChangeType == ChangeType.Deleted)
            {
                await UpdateSubjectVisitImageDateAsync(subjectVisitId);
                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
                //删除检查级别临床数据
                await _iClinicalAnswerService.DeleteStudyClinical(new Service.Reading.Dto.DeleteStudyClinicalInDto()
                {
                    StudyId = context.Entity.Id,
                });
            }
        }
        public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken)
        {
            var subjectVisitId = await _noneDicomStudyRepository.Where(x => x.Id == context.Entity.NoneDicomStudyId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
            if (context.ChangeType == ChangeType.Deleted || context.ChangeType == ChangeType.Added)
            {
                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
            }
        }
        /// 
        /// 处理提交状态
        /// 
        /// 
        /// 
        public async Task UpdateSubjectVisitSubmitStateAsync(Guid subjectVisitId)
        {
            //一个访视下面有多个检查,所以需要检测 没有的时候才清空  非dicom 是检查文件  不是表记录
            if (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).SelectMany(t => t.StudyList).CountAsync() == 0 &&
                await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
                    .SelectMany(t => t.NoneDicomStudyList).SelectMany(u => u.NoneDicomFileList).CountAsync() == 0)
            {
                await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.ToSubmit,
                    u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted, SVENDTC = null, SVSTDTC = null, SubmitState = SubmitStateEnum.None }, true);
            }
            else
            {
                // 上传非Dicom 后  将状态改为待提交 分为普通上传 和QC后重传  普通上传时才改为待提交
                await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.None, u => new SubjectVisit() { SubmitState = SubmitStateEnum.ToSubmit }, true);
            }
        }
        /// 
        /// 处理访视拍片日期
        /// 
        /// 
        /// 
        private async Task UpdateSubjectVisitImageDateAsync(Guid subjectVisitId)
        {
            var svTime = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new
            {
                DicomStudyMinStudyTime = t.StudyList.Min(t => (DateTime?)t.StudyTime),
                DicomStudyMaxStudyTime = t.StudyList.Max(t => (DateTime?)t.StudyTime),
                NoneDicomStudyMinStudyTime = t.NoneDicomStudyList.Min(t => (DateTime?)t.ImageDate),
                NoneDicomStudyMaxStudyTime = t.NoneDicomStudyList.Max(t => (DateTime?)t.ImageDate)
            }).FirstOrDefault().IfNullThrowException();
            var minArray = new DateTime?[] { svTime.DicomStudyMinStudyTime, svTime.NoneDicomStudyMinStudyTime };
            var maxArray = new DateTime?[] { svTime.DicomStudyMaxStudyTime, svTime.NoneDicomStudyMaxStudyTime };
            await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit()
            {
                EarliestScanDate = minArray.Min(),
                LatestScanDate = maxArray.Max()
            });
            if (minArray.Min() == null && maxArray.Max() == null)
            {
                await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit()
                {
                    VisitExecuted = VisitExecutedEnum.UnExecuted
                });
            }
            else
            {
                await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit()
                {
                    VisitExecuted = VisitExecutedEnum.Executed
                });
            }
        }
    }
}