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

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

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 分配规则
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TaskAllocationRuleService(IRepository<TaskAllocationRule> _taskAllocationRuleRepository,
        IRepository<UserRole> _userRoleRepository,
        IRepository<Enroll> _enrollRepository,
        IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
        IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository,
        IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskAllocationRuleService
    {



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

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

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

            return ResponseOutput.Ok(list, trialTaskConfig);
        }




        [TrialGlobalLimit("AfterStopCannNotOpt")]

        public async Task<IResponseOutput> 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<TaskAllocationRule>()
            {
                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<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(_localizer["TaskAllocation_TaskAssigned"]);
            }

            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, Guid trialReadingCriterionId)
        {
            var list = await _subjectCanceDoctorRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId).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.TaskAllocationRule.IsEnable*/ && /*(t.EnrollStatus >= EnrollStatus.ConfirmIntoGroup ||*/ t.Trial.SubjectDoctorUserList.Any(v => v.DoctorUserId == t.DoctorUser.Id))
                        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<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 _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 废弃
        /// <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


    }
}
