//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-06-07 14:10:49 
//     对此文件的更改可能会导致不正确的行为，并且如果重新生成代码，这些更改将会丢失。
//--------------------------------------------------------------------

using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Contracts;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 访视读片任务
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class VisitTaskService : BaseService
    {

        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository<SubjectUser> _subjectUserRepository;

        private readonly IRepository<ReadModule> _readModuleRepository;

        private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;


        public VisitTaskService(IRepository<VisitTask> visitTaskRepository, IRepository<Trial> trialRepository, IRepository<SubjectVisit> subjectVisitRepository,
            IRepository<Subject> subjectRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<TaskAllocationRule> taskAllocationRuleRepository,
            IRepository<ReadModule> readModuleRepository, IRepository<VisitTaskReReading> visitTaskReReadingRepository
            )
        {
            _taskAllocationRuleRepository = taskAllocationRuleRepository;
            _visitTaskRepository = visitTaskRepository;
            _trialRepository = trialRepository;
            _subjectVisitRepository = subjectVisitRepository;
            _subjectRepository = subjectRepository;
            _subjectUserRepository = subjectUserRepository;
            _readModuleRepository = readModuleRepository;
            _visitTaskReReadingRepository = visitTaskReReadingRepository;
        }


        /// <summary>
        /// 获取手动分配  未分配的Subject列表(IsHaveAssigned 传递false)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<SubjectAssignView>> GetSubjectAssignList(SubjectAssignQuery querySubjectAssign)
        {
            var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId)
                  .WhereIf(querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                  .WhereIf(querySubjectAssign.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())

                  .WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId)
                  .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId)

                  .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                  .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
                  .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false && querySubjectAssign.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                  .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false && querySubjectAssign.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())


                  .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed))
                  .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == true && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed))

                  .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == false && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false))
                  .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == false && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false))

                  .WhereIf(querySubjectAssign.DoctorUserId != null && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId))
                  .WhereIf(querySubjectAssign.DoctorUserId != null && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId))
                  .ProjectTo<SubjectAssignView>(_mapper.ConfigurationProvider, new { isJudgeDoctor = querySubjectAssign.IsJudgeDoctor });

            var pageList = await subjectQuery.ToPagedListAsync(querySubjectAssign.PageIndex, querySubjectAssign.PageSize, string.IsNullOrWhiteSpace(querySubjectAssign.SortField) ? nameof(querySubjectAssign.SubjectId) : querySubjectAssign.SortField, querySubjectAssign.Asc);

            return pageList;
        }

        /// <summary>
        /// 获取随访  阅片期 全局  任务列表
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <param name="_visitTaskCommonService"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<VisitTaskView>, object)> GetVisitTaskList(VisitTaskQuery queryVisitTask, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {
            //以前访视未产生任务的，在查询这里要产生 
            var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync();

            await _visitTaskCommonService.GenerateVisitTaskAsync(queryVisitTask.TrialId, svIdList);


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge)

                .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.Subject.Code.Contains(queryVisitTask.SubjectCode))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
                .ProjectTo<VisitTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
            return (pageList, trialTaskConfig);
        }



        /// <summary>
        /// 获取裁判访视任务列表
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<JudgeVisitTaskView>/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery queryVisitTask)
        {

            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                .Where(t => t.ReadingCategory == ReadingCategory.Judge)

                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.Subject.Code.Contains(queryVisitTask.SubjectCode))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
                .ProjectTo<JudgeVisitTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
            //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

            //return (pageList, trialTaskConfig);
        }



        /// <summary>
        /// 获取影像阅片列表 （排除重阅的） 相比而言多了几个字段 和配置信息
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<ReadingTaskView>, object)> GetReadingTaskList(VisitTaskQuery queryVisitTask)
        {
            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                .Where(t => t.IsReReadingCreate == false && t.DoctorUserId != null)

               .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
               .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
               .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
               .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
               .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
               .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
               .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.Subject.Code.Contains(queryVisitTask.SubjectCode))
               .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
               .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
               .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();

            return (pageList, trialTaskConfig);
        }


        /// <summary>
        /// 一致性分析列表  (自身 组内  最后勾选 产生的任务)
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ReadingTaskView>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask)
        {
            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                .Where(t => t.IsAnalysisCreate)

               .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
               .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
               .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
               .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
               .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
               .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
               .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.Subject.Code.Contains(queryVisitTask.SubjectCode))
               .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
               .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
               .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return (pageList);
        }


        [HttpPost]
        public async Task<List<SelfConsistentView>> GetSelfConsistentList(SelfConsistentQuery inQuery)
        {
            var query =   _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.DoctorUserId == inQuery.AnalysisDoctorUserId)
                                            .Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
                                            .Where(t => t.SignTime!.Value.AddDays(inQuery.IntervalWeeks * 7 + 1) > DateTime.Now)
                                            //重阅产生的访视任务  要把之前的访视任务去除
                                            .Where(t => t.ReReadingApplyState != ReReadingApplyState.Agree)
                                            .WhereIf(inQuery.IsHaveReadingPeriod == false, t => t.ReadingCategory == ReadingCategory.Visit)
                                            .WhereIf(inQuery.IsHaveReadingPeriod == true, t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)
                                            .GroupBy(t => new { t.SubjectId, /*t.TrialId, t.Subject.SiteId,*/ t.Subject.Code, t.Subject.TrialSite.TrialSiteCode })
                                            .Select(g => new SelfConsistentView()
                                            {
                                                SubjectId = g.Key.SubjectId,
                                                //TrialId = g.Key.TrialId,
                                                //SiteId = g.Key.SiteId,

                                                SubjectCode = g.Key.Code,
                                                TrialSiteCode = g.Key.TrialSiteCode,

                                                VisitTaskList = g.OrderBy(t => t.SubjectVisit.VisitNum).Select(c => new VisitTaskSimpleView()
                                                {
                                                    Id = c.Id,
                                                    ReadingCategory = c.ReadingCategory,
                                                    TaskBlindName = c.TaskBlindName,
                                                    TaskCode = c.TaskCode,
                                                    TaskName = c.TaskName,
                                                    TaskState = c.TaskState,
                                                    ArmEnum=c.ArmEnum,
                                                    SubjectId=c.SubjectId,
                                                    TrialId = c.TrialId
                                                }).ToList(),

                                                VisitValidTaskCount = g.Count()

                                            });

            return query.ToList();
        }



        /// <summary>
        /// 获取重阅影像阅片列表 
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ReReadingTaskView>> GetReReadingTaskList(VisitTaskQuery queryVisitTask)
        {


            var visitTaskQueryable = _visitTaskReReadingRepository
                .Where(t => t.NewReReadingTask.TrialId == queryVisitTask.TrialId)
                 .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
                 .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode))

                .WhereIf(queryVisitTask.SiteId != null, t => t.NewReReadingTask.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.NewReReadingTask.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.NewReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.NewReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.NewReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.NewReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.NewReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.NewReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.NewReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.NewReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
                .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }


        /// <summary>
        /// IR  待阅片任务列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<IRUnReadSubjectView>, object)> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery)
        {
            var trialId = iRUnReadSubjectQuery.TrialId;

            #region 按照任务的维度统计分组

            //var query = _visitTaskRepository.Where(t => t.TrialId == trialId)
            //  .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState != ReadingTaskState.HaveSigned)
            //  .GroupBy(t => new { t.SubjectId, t.Subject.Code })
            //  .Select(g => new IRUnReadSubjectView()
            //  {
            //      SubjectCode = g.Key.Code,
            //      SubjectId = g.Key.SubjectId,
            //      UnReadTaskCount = g.Count(),
            //      UnReadTaskList = g.AsQueryable().Select(c => new IRUnreadTaskView() { Id = c.Id, SuggesteFinishedTime = c.SuggesteFinishedTime, IsUrgent = c.IsUrgent }).ToList()
            //  });
            //return query.ToList();
            #endregion


            #region 按照Subject 维度
            var isReadingTaskViewInOrder = await _trialRepository.Where(x => x.Id == iRUnReadSubjectQuery.TrialId).Select(x => x.IsReadingTaskViewInOrder).FirstOrDefaultAsync();
            if (isReadingTaskViewInOrder)
            {
                var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId)
               .Where(t => t.SubjectDoctorList.Any(t => t.DoctorUserId == _userInfo.Id))
               .WhereIf(!string.IsNullOrEmpty(iRUnReadSubjectQuery.SubjectCode), t => t.Code.Contains(iRUnReadSubjectQuery.SubjectCode))
               .Select(s => new IRUnReadSubjectView()
               {
                   SubjectId = s.Id,
                   SubjectCode = s.Code,
                   UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id),
                   UnReadTaskList = s.SubjectVisitTaskList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id)
                   .Select(u => new IRUnreadTaskView() { Id = u.Id, IsUrgent = u.IsUrgent, SuggesteFinishedTime = u.SuggesteFinishedTime }).ToList(),
               })
                .Where(t => t.UnReadTaskCount > 0);


                var result = await subjectQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);
                return (result, new
                {
                    RandomReadInfo = new IRUnReadOutDto(),
                    IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
                });
            }
            else
            {

                var taskQuery = _visitTaskRepository.Where(x => x.TrialId == iRUnReadSubjectQuery.TrialId && x.DoctorUserId == _userInfo.Id);

                IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto()
                {

                    FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
                    FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
                    SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime),
                    UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
                    UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
                };

                return (new PageOutput<IRUnReadSubjectView>(), new
                {
                    IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
                    RandomReadInfo = iRUnReadOut,
                });

            }



            #endregion


        }


        /// <summary>
        /// IR  已阅片任务
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery queryVisitTask)
        {


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                 .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据


                .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.Subject.Code.Contains(queryVisitTask.SubjectCode))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
                .ProjectTo<IRHaveReadView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }


        /// <summary>
        /// 获取IR 重阅影像阅片列表 
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<IRReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask)
        {

            var visitTaskQueryable = _visitTaskReReadingRepository
                .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id)
                .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId)
                .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
                 .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode))
                .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate.Value.AddDays(1))
                .ProjectTo<IRReReadingTaskView>(_mapper.ConfigurationProvider);



            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }






        /// <summary>
        /// 批量为 多个Subject 分配医生  手动分配  IsReAssign 为true 批量删除 重新分配
        /// </summary>
        /// <param name="assginSubjectDoctorCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand)
        {
            var trialId = assginSubjectDoctorCommand.TrialId;
            var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList();

            if (assginSubjectDoctorCommand.IsJudgeDoctor)
            {
                if (assginSubjectDoctorCommand.IsReAssign)
                {

                    if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm))
                    {
                        throw new BusinessValidationFailedException("有Subject任务已应用，不允许重新分配");
                    }


                    await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm);
                }


            }
            else
            {
                if (assginSubjectDoctorCommand.IsReAssign)
                {

                    if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm))
                    {
                        throw new BusinessValidationFailedException("有Subject任务已应用，不允许重新分配");
                    }


                    await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm);
                }



            }
            foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList)
            {
                foreach (var doctorUserId in doctorUserIdList)
                {

                    var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum;


                    if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.OrignalSubjectUserId == null))
                    {
                        throw new BusinessValidationFailedException("有Subject 在其他Arm组已有该医生，不允许在新的组添加该医生");
                    }

                    if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.OrignalSubjectUserId == null))
                    {
                        throw new BusinessValidationFailedException("有Subject 已有该Arm组的医生，不允许继续分配,请刷新页面，确认页面数据是否过期");
                    }
                    else
                    {
                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now });

                    }

                }

            }


            await _subjectUserRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 批量取消Subject 分配的医生
        /// </summary>
        /// <returns></returns> 数量
        [HttpPost]
        public async Task<IResponseOutput> CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand)
        {
            if (cancelSubjectAssignCommand.IsJudgeDoctor)
            {
                foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList)
                {
                    if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm))
                    {
                        throw new BusinessValidationFailedException("有Subject任务已应用，不允许取消分配");
                    }

                    await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm);
                }
            }
            else
            {
                foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList)
                {
                    if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm))
                    {
                        throw new BusinessValidationFailedException("有Subject任务已应用，不允许取消分配");
                    }

                    await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm);
                }
            }

            await _subjectUserRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 手动分配确认  绑定该Subject的已存在的任务给医生
        /// </summary>
        /// <param name="assignConfirmCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand)
        {
            var trialId = assignConfirmCommand.TrialId;

            //获取项目配置 判断应该分配几个医生
            //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException();

            //需要确认的Subject  
            var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList();

            //将关系确认
            if (assignConfirmCommand.SubjectDoctorUserList.Count == 0)
            {
                await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.OrignalSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true });
            }
            else
            {
                await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.OrignalSubjectUserId == null
                && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true });
            }


            var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true)
                    .WhereIf(subjectIdList.Count() > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                    .WhereIf(subjectIdList.Count() > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
                   .ToList();


            foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId))
            {
                var subjectId = subjectTaskGroup.Key;



                //如果数据为空 那么就是确认所有已分配的
                List<DoctorArm> subjectDoctorIdArmList = new List<DoctorArm>();

                if (assignConfirmCommand.SubjectDoctorUserList.Count == 0)
                {

                    subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.OrignalSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList();


                }
                else
                {
                    subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList;

                }


                foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList())
                {

                    var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault();

                    if (subjectDoctorArm != null)
                    {
                        task.DoctorUserId = subjectDoctorArm.DoctorUserId;
                        task.AllocateTime = DateTime.Now;
                        task.TaskAllocationState = TaskAllocationState.Allocated;

                        task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7);

                        await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading });

                        await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading });


                    }
                    else
                    {
                        throw new BusinessValidationFailedException("在配置表中未找到配置的医生,无法应用绑定,请核对数据");
                    }

                }
            }



            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }




        /// <summary>
        /// 自动一次性分配所有未分配的  Subject 给医生  
        /// </summary>
        /// <param name="autoSubjectAssignCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand)
        {
            //自动分配的话，需要把手动分配的给删掉


            var trialId = autoSubjectAssignCommand.TrialId;
            var isJudge = autoSubjectAssignCommand.IsJudgeDoctor;


            //获取项目配置 判断应该分配几个医生
            var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException();


            //获取 已产生任务的Subject 目前分配情况
            var subjectList = _subjectRepository.Where(t => t.TrialId == trialId)
                .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
                .Select(t => new
                {
                    SubjectId = t.Id,

                    //给Subject分配医生的时候， 未确认绑定关系的
                    DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }),
                    IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null)
                }).ToList();

            //已产生任务的Subject数量（裁判情况下，就是产生裁判任务Subject 的数量）
            var subjectCount = subjectList.Count;

            //获取医生列表(裁判是裁判的医生列表)
            var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable)
                .Where(t => t.IsJudgeDoctor == isJudge)
                .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount })
                .ToList();


            //已分配的 医生的情况
            var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, DoctorUserId = c.DoctorUserId, c.ArmEnum })).ToList();

            //将目前已分配的情况 换到医生的维度
            foreach (var waitAllocationDoctor in waitAllocationDoctorList)
            {
                waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId)
                    .Select(g => new SubjectArm()
                    {
                        SubjectId = g.SubjectId,
                        ArmEnum = g.ArmEnum
                    }).ToList();
            }


            #region 完全按照Subject 遍历去分



            //仅仅分配未应用的 而且 没有分配医生的
            foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any()))
            {
                //该Subject  已经分配的医生数量
                var hasAssignDoctorCount = subject.DoctorUserList.Count();

                if (isJudge)
                {
                    if (hasAssignDoctorCount > 1)
                    {
                        throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1");

                    }

                    var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault();

                    //将分配结果记录
                    waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm()
                    {
                        SubjectId = subject.SubjectId,
                        ArmEnum = Arm.JudgeArm
                    });

                    await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now });

                }
                else
                {

                    //分配两个医生
                    if (trialConfig.ReadingType == ReadingMethod.Double)
                    {


                        if (hasAssignDoctorCount > 2)
                        {
                            throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2");

                        }

                        var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList();


                        #region 看阅片人之前在Subject哪个组做的多

                        var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId)
                              .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum)
                              .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() })
                              .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum;

                        var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId)
                                .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum)
                                .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() })
                                .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum;

                        //存放医生分配的Arm
                        var doctor1Arm = Arm.DoubleReadingArm1;
                        var doctor2Arm = Arm.DoubleReadingArm2;

                        if ((preferredDoctor1Arm == null && preferredDoctor2Arm == null) ||
                            (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2) ||
                            (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null) ||
                            (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2)
                            )
                        {
                            doctor1Arm = Arm.DoubleReadingArm1;
                            doctor2Arm = Arm.DoubleReadingArm2;
                        }
                        else if ((preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1) ||
                            (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1) ||
                            (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null))
                        {
                            doctor1Arm = Arm.DoubleReadingArm2;
                            doctor2Arm = Arm.DoubleReadingArm1;
                        }

                        else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1)
                        {
                            doctor1Arm = Arm.DoubleReadingArm1;
                            doctor2Arm = Arm.DoubleReadingArm2;
                        }
                        else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2)
                        {
                            doctor1Arm = Arm.DoubleReadingArm2;
                            doctor2Arm = Arm.DoubleReadingArm1;
                        }

                        #endregion


                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now });


                        //将分配结果记录
                        waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm()
                        {
                            SubjectId = subject.SubjectId,
                            ArmEnum = doctor1Arm
                        });


                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now });

                        //将分配结果记录
                        waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm()
                        {
                            SubjectId = subject.SubjectId,
                            ArmEnum = doctor2Arm
                        });
                    }
                    else if (trialConfig.ReadingType == ReadingMethod.Single)
                    {
                        if (hasAssignDoctorCount > 1)
                        {
                            throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1");
                        }

                        var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault();

                        //将分配结果记录
                        waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm()
                        {
                            SubjectId = subject.SubjectId,
                            ArmEnum = Arm.SingleReadingArm
                        });

                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now });

                    }

                }

            }


            #endregion







            await _subjectUserRepository.SaveChangesAsync();
            return ResponseOutput.Ok();

        }


        /// <summary>
        /// 任务  手动分配  重新分配  确认  取消分配
        /// </summary>分配
        /// <param name="assignSubjectTaskToDoctorCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand)
        {
            var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id);

            if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
            {
                //手动分配验证规则

                if (visitTask.SourceSubjectVisitId != null)
                {

                    if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id))
                    {
                        return ResponseOutput.NotOk("其中一个任务已分配给该医生，不允许分配");
                    }
                }
                else if (visitTask.SouceReadModuleId != null)
                {
                    if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id))
                    {
                        return ResponseOutput.NotOk("其中一个任务已分配给该医生，不允许分配");
                    }
                }
                else
                {
                    throw new BusinessValidationFailedException("出现脏数据  任务来源字段没有值");
                }



                visitTask.AllocateTime = DateTime.Now;
                visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId;
                visitTask.TaskAllocationState = TaskAllocationState.Allocated;

                await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading });

                await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading });
            }

            else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
            {
                //验证 是不是两个任务都给了同一个医生



                //是否删除配置规则表里的  Subject  医生绑定关系    重新添加绑定关系

                //是否其该Subject  其他访视 绑定的医生  也同时变更?


            }

            else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm)
            {
                visitTask.TaskAllocationState = TaskAllocationState.Allocated;
            }
            else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign)
            {
                visitTask.AllocateTime = null;
                visitTask.DoctorUserId = null;
                visitTask.TaskAllocationState = TaskAllocationState.NotAllocate;

                await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate });

                await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate });
            }
            await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 申请重阅  1:IR  2:PM
        /// </summary>
        /// <param name="applyReReadingCommand"></param>
        /// <param name="_visitTaskCommonService"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> ApplyReReading(ApplyReReadingCommand applyReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {
            var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).Include(t => t.JudgeVisitTask).ToListAsync();



            foreach (var task in taskList)
            {
                if (task.ReReadingApplyState == ReReadingApplyState.HaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree)
                {
                    throw new BusinessValidationFailedException("重阅已申请，或者重阅已同意状态下不允许申请重阅");
                }

                if(task.ReadingCategory == ReadingCategory.Judge && task.TaskState== TaskState.HaveReturned)
                {
                    throw new BusinessValidationFailedException("访视重阅导致裁判任务重置的，不能申请重阅");
                }

                task.ReReadingApplyState = ReReadingApplyState.HaveApplyed;

                //产生了裁判
                if (task.JudgeVisitTaskId != null)
                {
                    if (task.ReadingTaskState == ReadingTaskState.WaitReading || task.ReadingTaskState == ReadingTaskState.Reading)
                    {
                        task.JudgeVisitTask.TaskState = TaskState.Adbandon;
                    }
                    else
                    {

                        task.JudgeVisitTask.TaskState = TaskState.HaveReturned;


                    }
                }
            }

            //产生的新任务，状态保持跟申请的一直
            var reReadingTaskList = taskList.Clone();

            await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
            {
                TrialId = applyReReadingCommand.TrialId,
                ReadingCategory = ReadingCategory.ReReading,


                ReReadingApplyGenerateTaskCommand = new ReReadingApplyGenerateTaskCommand()
                {
                    RequestReReadingReason = applyReReadingCommand.RequestReReadingReason,
                    RequestReReadingType = applyReReadingCommand.RequestReReadingType,
                    ReReadingTaskList = reReadingTaskList
                }
            });

            //产生新的任务

            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 确认重阅与否  1同意 2 拒绝
        /// </summary>
        /// <param name="agreeReReadingCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand)
        {


            foreach (var item in agreeReReadingCommand.ConfirmReReadingList)
            {
                await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == item.OriginalReReadingTaskId, u => new VisitTask()
                {
                    ReReadingApplyState = (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject),
                    TaskState = (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : TaskState.Effect) 

                });

                await _visitTaskReReadingRepository.UpdatePartialFromQueryAsync(t => t.Id == item.Id, u => new VisitTaskReReading()
                {
                    RequestReReadingConfirmUserId = _userInfo.Id,
                    RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum,
                    RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason
                });

                if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree)
                {
                    if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer)
                    {
                        await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == item.NewReReadingTaskId, u => new VisitTask()
                        {
                            TaskState = TaskState.Effect
                        });
                    }
                    //立即分配
                    else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
                    {
                        var doctorUserId = await _visitTaskRepository.Where(t => t.Id == item.OriginalReReadingTaskId).Select(t => t.DoctorUserId).FirstOrDefaultAsync();

                        await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == item.NewReReadingTaskId, u => new VisitTask()
                        {
                            TaskState = TaskState.Effect,
                            DoctorUserId = doctorUserId,
                            TaskAllocationState=TaskAllocationState.Allocated,
                            AllocateTime = DateTime.Now,
                        });
                    }
                }

            }


            await _visitTaskRepository.SaveChangesAsync();



            return ResponseOutput.Ok();
        }





    }
}
