using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Domain.Share;

namespace IRaCIS.Core.Application.Triggers
{
    public class SubjectVisitImageDateTrigger : IAfterSaveTrigger<NoneDicomStudy>, IAfterSaveTrigger<DicomStudy>
    {
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;

        public SubjectVisitImageDateTrigger(IRepository<SubjectVisit> subjectVisitRepository)
        {
            _subjectVisitRepository = subjectVisitRepository;
        }

        //注意删除不能用扩展方法,必须用EF跟踪的实体  否则不能取到  SubjectVisitId
        public async Task AfterSave(ITriggerContext<NoneDicomStudy> context, CancellationToken cancellationToken)
        {
            var subjectVisitId = context.Entity.SubjectVisitId;

            if (context.ChangeType == ChangeType.Added || context.ChangeType == ChangeType.Modified)
            {
                await UpdateSubjectVisitImageDateAsync(context.Entity.SubjectVisitId);

                await _subjectVisitRepository.BatchUpdateAsync(t => t.Id == subjectVisitId, u => new SubjectVisit()
                {
                    VisitExecuted = VisitExecutedEnum.Executed
                });
            }


            if (context.ChangeType == ChangeType.Deleted)
            {
                await UpdateSubjectVisitImageDateAsync(context.Entity.SubjectVisitId);

                await UpdateSubjectVisitSubmitStateAsync(subjectVisitId);
            }
        }

        public async Task AfterSave(ITriggerContext<DicomStudy> context, CancellationToken cancellationToken)
        {
            var subjectVisitId = context.Entity.SubjectVisitId;
            if (context.ChangeType == ChangeType.Added )
            {
                await UpdateSubjectVisitImageDateAsync(subjectVisitId);

                await _subjectVisitRepository.BatchUpdateAsync(t => t.Id == subjectVisitId, u => new SubjectVisit()
                {
                    VisitExecuted = VisitExecutedEnum.Executed
                });
            }

            if (context.ChangeType == ChangeType.Deleted)
            {
                await UpdateSubjectVisitImageDateAsync(subjectVisitId);

                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.BatchUpdateAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.ToSubmit,
                    u => new SubjectVisit() { VisitExecuted = 0, SVENDTC = null, SVSTDTC = null, SubmitState = SubmitStateEnum.None });
            }
        }


        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.BatchUpdateAsync(t=>t.Id ==subjectVisitId, u => new SubjectVisit()
            {

                EarliestScanDate = minArray.Min(),

                LatestScanDate = maxArray.Max()
            });
        }
    }
}