//--------------------------------------------------------------------
//     此代码由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;


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

        /// <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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .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.OriginalReReadingId == null && 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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
               .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<TrialTaskConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

            return (pageList, trialTaskConfig);
        }

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


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                 .WhereIf(queryVisitTask.OriginalReReadingId != null, t => t.OriginalReReadingId == queryVisitTask.OriginalReReadingId)
                 .WhereIf(queryVisitTask.OriginalReReadingId == null, t => t.OriginalReReadingId != 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.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .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<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  待阅片任务列表(Subject 维度统计)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<IRUnReadSubjectView>> 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 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);


            return await subjectQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);


            #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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .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<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask)
        {


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                .Where(t => t.DoctorUserId == _userInfo.Id)
                .WhereIf(queryVisitTask.OriginalReReadingId != null, t => t.OriginalReReadingId == queryVisitTask.OriginalReReadingId)
                .WhereIf(queryVisitTask.OriginalReReadingId == null, t => t.OriginalReReadingId != 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.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .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<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>
        /// 获取手动分配  未分配的Subject列表(IsHaveAssigned 传递false)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<SubjectAssignView>> GetSubjectAssignList(SubjectAssignQuery querySubjectAssign)
        {
            var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId)
                  .Where(t => t.SubjectVisitTaskList.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, t => t.SubjectDoctorList.Count() > 0)
                  .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false, t => !t.SubjectDoctorList.Any())
                  .WhereIf(querySubjectAssign.IsHaveApplyedTask != null && querySubjectAssign.IsHaveApplyedTask == true, t => t.SubjectDoctorList.SelectMany(t => t.Subject.SubjectVisitTaskList).All(u => u.DoctorUserId != null))
                  .WhereIf(querySubjectAssign.IsHaveApplyedTask != null && querySubjectAssign.IsHaveApplyedTask == false, t => t.SubjectDoctorList.SelectMany(t => t.Subject.SubjectVisitTaskList).Any(u => u.DoctorUserId == null))
                  .WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId))
                  .ProjectTo<SubjectAssignView>(_mapper.ConfigurationProvider);

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

            return pageList;
        }


        /// <summary>
        /// 批量为 多个Subject 分配医生  手动分配  IsReAssign 为true 批量删除 重新分配
        /// </summary>
        /// <param name="assginSubjectDoctorCommand"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand)
        {

            var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList();

            if (assginSubjectDoctorCommand.IsReAssign)
            {

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


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

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

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

                    await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = assginSubjectDoctorCommand.TrialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now });
                }
                //await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = true });

            }

            await _subjectUserRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }

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

                await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId);
                //await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = false });
            }


            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();

            var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true)
                    .WhereIf(subjectIdList.Count() > 0, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.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).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.TaskState = TaskState.Allocated;

                        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("当前提交 Subject  以及医生所在Arm 与任务的Arm不一致,无法绑定,请核对数据");
                    }

                }
            }



            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;


            //获取 已产生任务的Subject 目前分配情况
            var subjectList = _subjectRepository.Where(t => t.TrialId == trialId).Where(t => t.SubjectVisitTaskList.Any())
                .Select(t => new { SubjectId = t.Id, DoctorUserList = t.SubjectDoctorList.Select(t => new { t.DoctorUserId, t.ArmEnum }), IsApplyed = t.SubjectVisitTaskList.Any(c => c.DoctorUserId != null) }).ToList();



            //获取项目配置 判断应该分配几个医生
            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();





            #region 按照医生维度分配Subject

            ////受试者总数
            //var subjectCount = subjectList.Count();

            ////获取待分配的医生列表  指导分配医生的数量
            //var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable)
            //    .Select(t => new { t.DoctorUserId, t.PlanReadingRatio, Weight = (subjectCount * t.PlanReadingRatio) % 100 })
            //    .OrderByDescending(t => t.PlanReadingRatio).ThenByDescending(t => t.Weight).ToList();

            ////给医生分配Subject 前验证  已经分配的数据是否符合分配的规范 
            //foreach (var subject in subjectList)
            //{
            //    var doctorCount = subject.DoctorUserList.Count();
            //    //分配两个医生
            //    if (trialConfig.ReadingType == ReadingMethod.Double)
            //    {

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

            //    }
            //    else if (trialConfig.ReadingType == ReadingMethod.Single)
            //    {
            //        if (doctorCount > 1)
            //        {
            //            throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1");
            //        }
            //    }
            //}

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

            //if (trialConfig.ReadingType == ReadingMethod.Single)
            //{
            //    //eg : 10个Sujbect  都是1/4     先分配整数  再分配  10%4=2个

            //    //特殊: 不够分的subject数量    适用于 2个Subject  4个医生 这种


            //    var integerPlan = 0;

            //    waitAllocationDoctorList.ForEach(doctor =>
            //    {

            //        integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio) / 100);

            //    });


            //    var specialSubjectCount = subjectCount - integerPlan;

            //    //按照医生维度 分配Subject  
            //    foreach (var doctor in waitAllocationDoctorList)
            //    {


            //        //该医生的目前已分配到的受试者
            //        var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).Distinct().ToList();

            //        //已分配的Subject 数量
            //        var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count();

            //        //该医生计划分配到的Subject  最接近的整数数量
            //        var planSubjectCount = (int)Math.Ceiling((double)(subjectCount * doctor.PlanReadingRatio) / 100);

            //        //权重大的,将特殊的分配
            //        if (doctor.Weight != 50)
            //        {
            //            if (specialSubjectCount > 0)
            //            {
            //                specialSubjectCount--;

            //                planSubjectCount++;
            //            }

            //        }

            //        //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject
            //        if (planSubjectCount > hasAssignedSubjectCount)
            //        {

            //            //从未分配的Subjct找到可以分配的分配给该医生

            //            var allAssignedSubjectIdList = assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().ToList();

            //            //取需要分配的数量  并且没有分配给其他医生的包括自己
            //            var assignSubjectIdList = subjectList.Where(t => !allAssignedSubjectIdList.Contains(t.SubjectId)).Select(t => t.SubjectId).Take(planSubjectCount - hasAssignedSubjectCount).ToList();

            //            foreach (var assignSubjectId in assignSubjectIdList)
            //            {
            //                //将分配结果记录
            //                assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 0 });

            //                await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, AssignTime = DateTime.Now });


            //            }
            //        }
            //        else
            //        {
            //            throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配");
            //        }

            //    }

            //}
            //if (trialConfig.ReadingType == ReadingMethod.Double)
            //{
            //    var integerPlan = 0;

            //    waitAllocationDoctorList.ForEach(doctor =>
            //    {

            //        integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100);

            //    });


            //    var specialSubjectCount = (subjectCount * 2) - integerPlan;

            //    //按照医生维度 分配Subject  
            //    foreach (var doctor in waitAllocationDoctorList)
            //    {


            //        //该医生的目前已分配到的受试者
            //        var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).ToList();

            //        //已分配的Subject 数量
            //        var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count();

            //        //该医生计划分配到的Subject  最接近的整数数量
            //        var planSubjectCount = (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100);

            //        //判断是否能整除

            //        var yuShu = (subjectCount * doctor.PlanReadingRatio * 2) % 100;

            //        if (yuShu != 0)
            //        {
            //            if (specialSubjectCount > 0)
            //            {
            //                specialSubjectCount--;
            //                planSubjectCount++;

            //            }
            //        }


            //        //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject
            //        if (planSubjectCount > hasAssignedSubjectCount)
            //        {

            //            //分配给其他医生  已经满了的
            //            var otherExceptDoctorIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId != doctor.DoctorUserId).GroupBy(t => t.SubjectId)
            //                .Select(g => new { SubjectId = g.Key, DoctorCount = g.Count() }).Where(c => c.DoctorCount == 2).Select(t => t.SubjectId).ToList();


            //            //取需要分配的数量  并且没有分配给其他医生的包括自己
            //            var assignSubjectIdList = subjectList.Where(t => !hasAssignedSubjectIdList.Contains(t.SubjectId) && !otherExceptDoctorIdList.Contains(t.SubjectId))
            //                .Select(t => t.SubjectId).Take((planSubjectCount - hasAssignedSubjectCount)).ToList();

            //            foreach (var assignSubjectId in assignSubjectIdList)
            //            {


            //                var otherHaveAssignedSubject = assignedSubjectDoctorList.Where(t => t.SubjectId == assignSubjectId).FirstOrDefault();

            //                if (otherHaveAssignedSubject != null)
            //                {

            //                    if (otherHaveAssignedSubject.ArmEnum == 1)
            //                    {
            //                        assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2 });

            //                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2, AssignTime = DateTime.Now });

            //                    }
            //                    else if (otherHaveAssignedSubject.ArmEnum == 2)
            //                    {
            //                        assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 });

            //                        await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now });

            //                    }
            //                }
            //                else
            //                {
            //                    assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 });

            //                    await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now });

            //                }


            //            }
            //        }
            //        else
            //        {
            //            throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配");
            //        }



            //    }



            //    //如果是2个Subject 3个医生 这种 都是百分之33的比率
            //    //     10         3 







            //}

            ////验证是否所有Subject  是否分配好

            //if (assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().Count() != subjectCount)
            //{
            //    throw new BusinessValidationFailedException("分配算法有问题,有Subject 未分配");
            //}

            #endregion



            #region 完全按照Subject 遍历去分

            var subjectCount = subjectList.Count;

            var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable)
                .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();
            }


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

                //分配两个医生
                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();


                    //将分配结果记录


                    //看阅片人之前在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;
                    }


                    //if(!waitAllocationDoctorList.Where(t=>t.DoctorUserId== allocateDoctorList[0].DoctorUserId).SelectMany(u => u.SubjectArmList).Any(t => t.SubjectId == subject.SubjectId))
                    //{
                    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
                    });
                    //}

                    //if (!waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SelectMany(u => u.SubjectArmList).Any(t => t.SubjectId == subject.SubjectId))
                    //{
                    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)
            {
                visitTask.AllocateTime = DateTime.Now;
                visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId;
                visitTask.TaskState = TaskState.Allocated;

            }

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



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

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


            }

            else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm)
            {
                visitTask.TaskState = TaskState.Allocated;
            }
            else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign)
            {
                visitTask.AllocateTime = null;
                visitTask.DoctorUserId = null;
                visitTask.TaskState = TaskState.NotAllocate;
            }
            await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }
    }
}