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

using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 一致性分析配置表
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TaskConsistentRuleService : BaseService, ITaskConsistentRuleService
    {

        private readonly IRepository<TaskConsistentRule> _taskConsistentRuleRepository;
        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<SubjectUser> _subjectUserRepository;
        private readonly IRepository<Subject> _subjectRepository;

        public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository ,IRepository<Subject> subjectRepository)
        {
            _taskConsistentRuleRepository = taskConsistentRuleRepository;
            _visitTaskRepository = visitTaskRepository;
            _subjectUserRepository = subjectUserRepository;
            _subjectRepository = subjectRepository;
        }


        /// <summary>
        /// 一致性分析列表  (自身 组内  最后勾选 产生的任务)
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<AnalysisTaskView>> 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<AnalysisTaskView>(_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>
        /// 为一致性分析医生,选择Subejct 列表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<DoctorConsistentRuleSubjectView>> GetDoctorConsistentRuleSubjectList(ConsistentQuery inQuery)
        {
            var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);


            bool isSelfAnalysis = filterObj.CompareDoctorUserId == null;

            IQueryable<Guid> subjectfilter = null;

            if (isSelfAnalysis == false)
            {
                //过滤不满足的Subject  

                subjectfilter = _subjectUserRepository.Where(t => t.TrialId == filterObj.TrialId).GroupBy(t => t.SubjectId)
                    .Where(g => g.Any(t => t.DoctorUserId == filterObj.AnalysisDoctorUserId) && !g.Any(t => t.DoctorUserId == filterObj.CompareDoctorUserId)).Select(g => g.Key);
            }

            var doctorUserId = isSelfAnalysis ? filterObj.AnalysisDoctorUserId : filterObj.CompareDoctorUserId;


            #region 以任务为维度
            var group = _visitTaskRepository.Where(t => t.TrialId == filterObj.TrialId && t.IsAnalysisCreate==false)
                                          //  自身一致性分析
                                          .WhereIf(isSelfAnalysis, t => t.DoctorUserId == filterObj.AnalysisDoctorUserId)
                                          // 组内一致性分析
                                          .WhereIf(isSelfAnalysis == false && subjectfilter != null, t => t.DoctorUserId == filterObj.AnalysisDoctorUserId && subjectfilter.Contains(t.SubjectId))
                                          .Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
                                          .Where(t => t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7 + 1) > DateTime.Now)
                                          //重阅产生的访视任务  要把之前的访视任务去除
                                          .Where(t => t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)

                                          .WhereIf(filterObj.IsHaveReadingPeriod == false, t => t.ReadingCategory == ReadingCategory.Visit)
                                          .WhereIf(filterObj.IsHaveReadingPeriod == true, t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)
                                          .GroupBy(t => t.SubjectId)
                                          .Where(g => g.Count() >= filterObj.PlanVisitCount);

            var query = group.Select(g => new DoctorConsistentRuleSubjectView()
            {
                SubjectId = g.Key,

                IsHaveGeneratedTask = g.Any(c => c.Subject.SubjectVisitTaskList.Any(t => t.IsAnalysisCreate && t.DoctorUserId == doctorUserId && t.TaskConsistentRuleId == filterObj.Id)),

                VisitTaskList = g.OrderBy(t => t.VisitTaskNum)

                .Select(c => new VisitTaskSimpleView()
                {
                    Id = c.Id,
                    ReadingCategory = c.ReadingCategory,
                    ReadingTaskState = c.ReadingTaskState,
                    TaskBlindName = c.TaskBlindName,
                    TaskCode = c.TaskCode,
                    TaskName = c.TaskName,
                    TaskState = c.TaskState,
                    ArmEnum = c.ArmEnum,
                    SubjectId = c.SubjectId,
                    TrialId = c.TrialId,
                    SiteId = c.Subject.SiteId,
                    SubjectCode = c.Subject.Code,
                    TrialSiteCode = c.Subject.TrialSite.TrialSiteCode,

                    RelationDoctorUserList=c.SameVisitTaskList/*Where(t=>t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)*/.Select(c=> new UserSimpleInfo()
                    {
                        FullName = c.DoctorUser.FullName,
                        UserCode = c.DoctorUser.UserCode,
                        UserId = c.DoctorUser.Id,
                        UserName = c.DoctorUser.UserName
                    }).ToList(),

                    IsHaveGeneratedTask = c.Subject.SubjectVisitTaskList.Any(t => t.IsAnalysisCreate && t.DoctorUserId == doctorUserId && t.TaskConsistentRuleId == filterObj.Id),

                }).ToList(),

                ValidTaskCount = g.Count()

            });
            #endregion



            var count = group.Count();

            query = query.OrderByDescending(t => t.IsHaveGeneratedTask).Skip((inQuery.PageIndex - 1) * inQuery.PageSize);
            var items = await query.Take(inQuery.PageSize).ToArrayAsync().ConfigureAwait(false);

            var pagedList = new PageOutput<DoctorConsistentRuleSubjectView>()
            {
                PageIndex = inQuery.PageIndex,
                PageSize = inQuery.PageSize,
                TotalCount = count,
                CurrentPageData = items
            };


            return pagedList;
        }

        /// <summary>
        /// 确认生成一致性分析任务
        /// </summary>
        /// <param name="inCommand"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> ConfirmGenerateConsistentTask(ConsistentConfirmGenerateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {
            var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TaskConsistentRuleId);

            bool isSelfAnalysis = filterObj.CompareDoctorUserId == null;

            IQueryable<Guid> subjectfilter = default;

            if (isSelfAnalysis == false)
            {
                //过滤不满足的Subject  

                subjectfilter = _subjectUserRepository.Where(t => t.TrialId == filterObj.TrialId).GroupBy(t => t.SubjectId)
                    .Where(g => g.Any(t => t.DoctorUserId == filterObj.AnalysisDoctorUserId) && !g.Any(t => t.DoctorUserId == filterObj.CompareDoctorUserId)).Select(g => g.Key);
            }

            var doctorUserId = isSelfAnalysis ? filterObj.AnalysisDoctorUserId : filterObj.CompareDoctorUserId;



            var group = _visitTaskRepository.Where(t => t.TrialId == filterObj.TrialId && inCommand.SubejctIdList.Contains(t.SubjectId) && t.IsAnalysisCreate == false)
                                        //  自身一致性分析
                                        .WhereIf(isSelfAnalysis, t => t.DoctorUserId == filterObj.AnalysisDoctorUserId)
                                        // 组内一致性分析
                                        .WhereIf(isSelfAnalysis == false && subjectfilter != null, t => t.DoctorUserId == filterObj.AnalysisDoctorUserId && subjectfilter.Contains(t.SubjectId))
                                        .Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
                                          .Where(t => t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7 + 1) > DateTime.Now)
                                          //重阅产生的访视任务  要把之前的访视任务去除
                                          .Where(t => t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)

                                        .WhereIf(filterObj.IsHaveReadingPeriod == false, t => t.ReadingCategory == ReadingCategory.Visit)
                                        .WhereIf(filterObj.IsHaveReadingPeriod == true, t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)
                                        .GroupBy(t => t.SubjectId)
                                        .Where(g => g.Count() >= filterObj.PlanVisitCount);


            var query = group.Select(g => new DoctorConsistentRuleSubjectView()
            {
                SubjectId = g.Key,

                IsHaveGeneratedTask = g.Any(c => c.Subject.SubjectVisitTaskList.Any(t => t.IsAnalysisCreate && t.DoctorUserId == doctorUserId && t.TaskConsistentRuleId == filterObj.Id)),

                VisitTaskList = g.OrderBy(t => t.VisitTaskNum).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,
                    SiteId = c.Subject.SiteId,
                    TrialId = c.TrialId,
                    SubjectCode = c.Subject.Code,
                    TrialSiteCode = c.Subject.TrialSite.TrialSiteCode,

                    IsHaveGeneratedTask = c.Subject.SubjectVisitTaskList.Any(t => t.IsAnalysisCreate && t.DoctorUserId == doctorUserId && t.TaskConsistentRuleId == filterObj.Id),

                }).ToList(),

                ValidTaskCount = g.Count()

            });

            var list = query.OrderByDescending(t=>t.IsHaveGeneratedTask).ToList();

            foreach (var subject in list)
            {
                subject.VisitTaskList.Take(filterObj.PlanVisitCount).ForEach(t => { t.DoctorUserId = doctorUserId; t.TaskConsistentRuleId = filterObj.Id; });


                await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
                {
                    TrialId = filterObj.TrialId,
                    ReadingCategory = ReadingCategory.Consistent,
                    GenerataConsistentTaskList = subject.VisitTaskList.Where(t=>t.IsHaveGeneratedTask==false).ToList()
                });

            }


            return ResponseOutput.Ok();


        }



        /// <summary>
        /// 一致性分配 配置+  统计已经生成数量统计表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<TaskConsistentRuleView>> GetTaskConsistentRuleList(TaskConsistentRuleQuery inQuery)
        {

            var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
                 .WhereIf(inQuery.IsSelfAnalysis, t => t.CompareDoctorUserId == null)
                 .WhereIf(inQuery.IsSelfAnalysis == false, t => t.CompareDoctorUserId != null)
                 .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);

            return await taskConsistentRuleQueryable.ToListAsync();
        }


        public async Task<IResponseOutput> AddOrUpdateTaskConsistentRule(TaskConsistentRuleAddOrEdit addOrEditTaskConsistentRule)
        {

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

            var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1);

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

        }


        [HttpDelete("{taskConsistentRuleId:guid}")]
        public async Task<IResponseOutput> DeleteTaskConsistentRule(Guid taskConsistentRuleId)
        {
            var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId);

            //自身一致性分析
            if (config.CompareDoctorUserId == null)
            {
                if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.DoctorUserId == config.AnalysisDoctorUserId && t.TrialId == config.TrialId))
                {
                    throw new BusinessValidationFailedException("已产生一致性分析任务,不允许删除");
                }
            }
            //组内一致性分析
            else
            {
                if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.DoctorUserId == config.CompareDoctorUserId && t.TrialId == config.TrialId))
                {
                    throw new BusinessValidationFailedException("已产生一致性分析任务,不允许删除");
                }
            }


            var success = await _taskConsistentRuleRepository.DeleteFromQueryAsync(t => t.Id == taskConsistentRuleId, true);
            return ResponseOutput.Ok();
        }





    }
}