//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-06-07 13:14:38 
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Service
{
    /// 
    /// 分配规则
    /// 	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TaskAllocationRuleService(IRepository _taskAllocationRuleRepository,
        IRepository _userRoleRepository,
        IRepository _enrollRepository,
        IRepository _readingQuestionCriterionTrialRepository,
        IRepository _subjectCanceDoctorRepository,
        IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskAllocationRuleService
    {
        /// 
        /// 获取计划列表  医生带阅片类型
        /// 
        /// 
        /// 
        public async Task>> GetDoctorPlanAllocationRuleList(Guid trialId)
        {
            var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
            //所有标准都是一样  后台只返回任意一个标准的就好了
            var trialTaskConfig = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync();
            return ResponseOutput.Ok(list, trialTaskConfig);
        }
        [TrialGlobalLimit( "AfterStopCannNotOpt" )]
        public async Task AddOrUpdateTaskAllocationRule(TaskAllocationRuleAddOrEdit addOrEditTaskAllocationRule)
        {
            //冗余 存
            var enrollId = _enrollRepository.Where(t => t.TrialId == addOrEditTaskAllocationRule.TrialId && t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId).Select(t => t.Id).FirstOrDefault();
            if (enrollId == Guid.Empty)
            {
                //"错误,未在入组表中找到该医生得账号Id"
                return ResponseOutput.NotOk(_localizer["TaskAllocation_DoctorIdNotFound"]);
            }
            addOrEditTaskAllocationRule.EnrollId = enrollId;
            var verifyExp1 = new EntityVerifyExp()
            {
                VerifyExp = t => t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId && t.TrialId == addOrEditTaskAllocationRule.TrialId,
                // "已有该医生配置,不允许继续增加"
                VerifyMsg = _localizer["TaskAllocation_DoctorConfigExists"]
            };
            var entity = await _taskAllocationRuleRepository.InsertOrUpdateAsync(addOrEditTaskAllocationRule, true, verifyExp1);
            return ResponseOutput.Ok(entity.Id.ToString());
        }
        [TrialGlobalLimit( "AfterStopCannNotOpt" )]
        [HttpDelete("{taskAllocationRuleId:guid}")]
        public async Task DeleteTaskAllocationRule(Guid taskAllocationRuleId)
        {
            if (await _taskAllocationRuleRepository.Where(t => t.Id == taskAllocationRuleId).AnyAsync(t => t.DoctorUser.VisitTaskList.Where(u => u.TrialId == t.TrialId).Any()))
            {
                //"已分配任务给该医生,不允许删除"
                return ResponseOutput.NotOk(_localizer["TaskAllocation_TaskAssigned"]);
            }
            var success = await _taskAllocationRuleRepository.DeleteFromQueryAsync(t => t.Id == taskAllocationRuleId, true);
            return ResponseOutput.Ok();
        }
        //public async Task AddSubjectCancelDoctorNote(CancelDoctorCommand command)
        //{
        //    await _subjectCanceDoctorRepository.InsertOrUpdateAsync(command, true);
        //    return ResponseOutput.Ok();
        //}
        public async Task> GetSubjectCancelDoctorHistoryList(Guid subjectId, Guid trialReadingCriterionId)
        {
            var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
            return list;
        }
        /// 
        /// 获取项目下 医生账户信息下拉
        /// 
        /// 
        /// 
        /// 
        [HttpGet("{trialId:guid}")]
        public async Task> GetDoctorUserSelectList(Guid trialId, [FromServices] IRepository _enrollRepository)
        {
            var query = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
                        join user in _userRoleRepository.AsQueryable() on enroll.DoctorId equals user.DoctorId
                        select new TrialDoctorUserSelectView()
                        {
                            TrialId = enroll.TrialId,
                            //ReadingType = enroll.Trial.ReadingType,
                            DoctorUserId = user.Id,
                            FullName = user.IdentityUser.FullName,
                            UserCode = user.IdentityUser.UserCode,
                            UserName = user.IdentityUser.UserName,
                            UserTypeEnum = user.UserTypeRole.UserTypeEnum,
                            ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList()
                        };
            return await query.ToListAsync();
        }
        [HttpPost]
        public async Task> GetDoctorSelectList(DoctorSelectQuery selectQuery, [FromServices] IRepository _enrollRepository)
        {
            var query = from allocationRule in _taskAllocationRuleRepository.Where(t => t.TrialId == selectQuery.TrialId && t.IsEnable)
                                              .WhereIf(selectQuery.ReadingCategory != null && selectQuery.TrialReadingCriterionId == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.ReadingCategory == selectQuery.ReadingCategory))
                                              .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory == null, t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId))
                                              .WhereIf(selectQuery.TrialReadingCriterionId != null && selectQuery.ReadingCategory != null,
                                                   t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && t.ReadingCategory == selectQuery.ReadingCategory))
                        join user in _userRoleRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
                        select new TrialDoctorUserSelectView()
                        {
                            TrialId = allocationRule.TrialId,
                            DoctorUserId = user.Id,
                            FullName = user.IdentityUser.FullName,
                            UserCode = user.IdentityUser.UserCode,
                            UserName = user.IdentityUser.UserName,
                            UserTypeEnum = user.UserTypeRole.UserTypeEnum,
                            ReadingCategoryList = selectQuery.TrialReadingCriterionId == null ?
                           allocationRule.Enroll.EnrollReadingCategoryList.Where(t => (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory)).Select(t => t.ReadingCategory).OrderBy(t => t).ToList() :
                           allocationRule.Enroll.EnrollReadingCategoryList
                           .Where(t => t.TrialReadingCriterionId == selectQuery.TrialReadingCriterionId && (selectQuery.ReadingCategory == null ? true : t.ReadingCategory == selectQuery.ReadingCategory))
                           .Select(t => t.ReadingCategory).OrderBy(t => t).ToList()
                        };
            return await query.ToListAsync();
        }
        #region 废弃
        /// 
        /// 获取访视任务   应用Subject后  医生比率情况
        /// 
        /// 
        [HttpPost]
        [Obsolete]
        public async Task> GetSubjectApplyDoctorTaskStatList(ApplySubjectCommand assignConfirmCommand)
        {
            var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.IsJudgeDoctor == assignConfirmCommand.IsJudgeDoctor)
            .ProjectTo(_mapper.ConfigurationProvider, new { subjectIdList = assignConfirmCommand.SubjectIdList, isJudgeDoctor = assignConfirmCommand.IsJudgeDoctor });
            return await taskAllocationRuleQueryable.ToListAsync();
        }
        [HttpPost]
        [Obsolete]
        public async Task> GetTaskAllocationRuleList(TaskAllocationRuleQuery queryTaskAllocationRule)
        {
            var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == queryTaskAllocationRule.TrialId /*&& t.IsJudgeDoctor == queryTaskAllocationRule.IsJudgeDoctor*/)
             .ProjectTo(_mapper.ConfigurationProvider);
            //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryTaskAllocationRule.TrialId).ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = queryTaskAllocationRule.IsJudgeDoctor }).FirstOrDefault();
            return await taskAllocationRuleQueryable.ToListAsync();
        }
        #endregion
    }
}