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

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

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 分配规则
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TaskAllocationRuleService : BaseService, ITaskAllocationRuleService
    {

        private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
        private readonly IRepository<User> _userRepository;

        private readonly IRepository<Trial> _trialRepository;

        private readonly IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository;



        public TaskAllocationRuleService(IRepository<TaskAllocationRule> taskAllocationRuleRepository, IRepository<User> userRepository, IRepository<Trial> trialRepository, IRepository<SubjectCanceDoctor> subjectCanceDoctorRepository)
        {
            _taskAllocationRuleRepository = taskAllocationRuleRepository;
            _userRepository = userRepository;
            _trialRepository = trialRepository;
            _subjectCanceDoctorRepository = subjectCanceDoctorRepository;
        }



        
        /// <summary>
        /// 获取计划列表  医生带阅片类型
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        public async Task<(List<TaskAllocationRuleDTO>,object)> GetDoctorPlanAllocationRuleList(Guid trialId)
        {

            var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId).ProjectTo<TaskAllocationRuleDTO>(_mapper.ConfigurationProvider).ToListAsync();

            //所有标准都是一样  后台只返回任意一个标准的就好了
            var trialTaskConfig = _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();

            return (list, trialTaskConfig);
        }




        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> AddOrUpdateTaskAllocationRule(TaskAllocationRuleAddOrEdit addOrEditTaskAllocationRule)
        {


            //冗余 存

            var enrollId = _repository.Where<Enroll>(t => t.TrialId == addOrEditTaskAllocationRule.TrialId && t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId).Select(t => t.Id).FirstOrDefault();

            if (enrollId == Guid.Empty)
            {
                return ResponseOutput.NotOk("错误，未在入组表中找到该医生得账号Id");
            }

            addOrEditTaskAllocationRule.EnrollId = enrollId;

            var verifyExp1 = new EntityVerifyExp<TaskAllocationRule>()
            {
                VerifyExp = t => t.DoctorUserId == addOrEditTaskAllocationRule.DoctorUserId && t.TrialId == addOrEditTaskAllocationRule.TrialId,
                VerifyMsg = "已有该医生配置，不允许继续增加"
            };

            var entity = await _taskAllocationRuleRepository.InsertOrUpdateAsync(addOrEditTaskAllocationRule, true, verifyExp1);

            return ResponseOutput.Ok(entity.Id.ToString());

        }

        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [HttpDelete("{taskAllocationRuleId:guid}")]
        public async Task<IResponseOutput> 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("已分配任务给该医生，不允许删除");
            }

            var success = await _taskAllocationRuleRepository.DeleteFromQueryAsync(t => t.Id == taskAllocationRuleId, true);


            return ResponseOutput.Ok();
        }


        //public async Task<IResponseOutput> AddSubjectCancelDoctorNote(CancelDoctorCommand command)
        //{
        //    await _subjectCanceDoctorRepository.InsertOrUpdateAsync(command, true);

        //    return ResponseOutput.Ok();
        //}

        public async Task<List<SubjectCancelDoctorView>> GetSubjectCancelDoctorHistoryList(Guid subjectId)
        {
            var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId).ProjectTo<SubjectCancelDoctorView>(_mapper.ConfigurationProvider).ToListAsync();

            return list;
        }






        /// <summary>
        /// 获取项目下 医生账户信息下拉
        /// </summary>
        /// <param name="trialId"></param>
        /// <param name="_enrollRepository"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<List<TrialDoctorUserSelectView>> GetDoctorUserSelectList(Guid trialId, [FromServices] IRepository<Enroll> _enrollRepository)
        {
            var query = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup)
                        join user in _userRepository.AsQueryable() on enroll.DoctorUserId equals user.Id
                        select new TrialDoctorUserSelectView()
                        {
                            TrialId = enroll.TrialId,
                            DoctorUserId = user.Id,
                            FullName = user.FullName,
                            UserCode = user.UserCode,
                            UserName = user.UserName,
                            UserTypeEnum = user.UserTypeRole.UserTypeEnum,
                            ReadingCategoryList = enroll.EnrollReadingCategoryList.Select(t => t.ReadingCategory).ToList()

                        };

            var list=  await query.ToListAsync();

            return list;
        }


        [HttpPost]
        public async Task<List<TrialDoctorUserSelectView>> GetDoctorSelectList(DoctorSelectQuery selectQuery, [FromServices] IRepository<Enroll> _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 _userRepository.AsQueryable() on allocationRule.DoctorUserId equals user.Id
                        select new TrialDoctorUserSelectView()
                        {
                            TrialId = allocationRule.TrialId,
                            DoctorUserId = user.Id,
                            FullName = user.FullName,
                            UserCode = user.UserCode,
                            UserName = user.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 废弃
        /// <summary>
        /// 获取检查批次任务   应用Subject后  医生比率情况
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task<List<DoctorVisitTaskStatView>> GetSubjectApplyDoctorTaskStatList(ApplySubjectCommand assignConfirmCommand)
        {
            var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.IsJudgeDoctor == assignConfirmCommand.IsJudgeDoctor)
            .ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider, new { subjectIdList = assignConfirmCommand.SubjectIdList, isJudgeDoctor = assignConfirmCommand.IsJudgeDoctor });

            return await taskAllocationRuleQueryable.ToListAsync();
        }



        [HttpPost]
        [Obsolete]
        public async Task<List<DoctorVisitTaskStatView>> GetTaskAllocationRuleList(TaskAllocationRuleQuery queryTaskAllocationRule)
        {
            var taskAllocationRuleQueryable = _taskAllocationRuleRepository.Where(t => t.TrialId == queryTaskAllocationRule.TrialId /*&& t.IsJudgeDoctor == queryTaskAllocationRule.IsJudgeDoctor*/)
             .ProjectTo<DoctorVisitTaskStatView>(_mapper.ConfigurationProvider);


            //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryTaskAllocationRule.TrialId).ProjectTo<TrialProcessConfigDTO>(_mapper.ConfigurationProvider, new { isJudgeDoctor = queryTaskAllocationRule.IsJudgeDoctor }).FirstOrDefault();

            return await taskAllocationRuleQueryable.ToListAsync();
        }

        #endregion


    }
}
