using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using MassTransit;
using Panda.DynamicWebApi.Attributes;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infra.EFCore.Common;
namespace IRaCIS.Application.Services
{
    /// 
    /// 生成的阅片模块(在大列表上展示的) 阅片期
    /// 
    [ApiExplorerSettings(GroupName = "Reading")]
    public class ReadModuleService :  BaseService
    {
        public IRepository _subjectVisitRepository;
        private readonly IRepository _subjectRepository;
        private readonly IRepository _visitstageRepository;
        private readonly IRepository _userRepository;
        private readonly IRepository _trialRepository;
        private readonly IRepository _clinicalDataTrialSetRepository;
        private readonly IRepository _readModuleViewRepository;
        private readonly IRepository _dicomInstanceRepository;
        private readonly IRepository _noneDicomStudyFileRepository;
        private readonly IRepository _readingPeriodSetRepository;
        private readonly IRepository _readModuleRepository;
        public ReadModuleService(IRepository subjectVisitRepository,
            IRepository subjectRepository,
            IRepository visitstageRepository,
            IRepository UserRepository,
            IRepository trialRepository,
            IRepository clinicalDataTrialSetRepository,
            IRepository readModuleViewRepository,
            IRepository dicomInstanceRepository,
            IRepository noneDicomStudyFileRepository,
            IRepository readingPeriodSetRepository,
            IRepository readModuleRepository
          )
        {
            this._subjectVisitRepository = subjectVisitRepository;
            this._subjectRepository = subjectRepository;
            this._visitstageRepository = visitstageRepository;
            this._userRepository = UserRepository;
            this._trialRepository = trialRepository;
            this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
            this._readModuleViewRepository = readModuleViewRepository;
            this._dicomInstanceRepository = dicomInstanceRepository;
            this._noneDicomStudyFileRepository = noneDicomStudyFileRepository;
            this._readingPeriodSetRepository = readingPeriodSetRepository;
            this._readModuleRepository = readModuleRepository;
        }
        /// 
        /// 获取读片计划列表  byZhouhang 
        /// 
        /// 
        /// 
        public async Task<(PageOutput, object)> GetReadPlanList(GetReadModuleDto dto)
        {
            var subjectQuery = _subjectRepository
               .WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
               .WhereIf(dto.SubjectId != null, x => x.Id == dto.SubjectId)
               .WhereIf(dto.TrialSiteCode != null, x => x.TrialSite.TrialSiteCode == dto.TrialSiteCode)
               .WhereIf(dto.SubjectCode != null, x => x.Code == dto.SubjectCode)
             
               
               
               .Select(x => new ReadPlanView
              {
                  TrialSiteCode = x.TrialSite.TrialSiteCode,
                  SiteCode = x.TrialSite.TrialSiteCode,
                  SiteId = x.SiteId,
                  SubjectCode = x.Code,
                  SubjectId = x.Id,
                  //Data = x.SubjectVisitList.OrderByDescending(y => y.VisitNum).Select(y => new GetReadModuleOutDto()
                  //{
                  //    Id = y.Id,  //id
                  //    Name = y.VisitName,
                  //    ModuleType = y.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit, // 模块类型
                  //    IsUrgent = x.IsUrgent, // 是否加急
                  //    SubjectVisitId = y.Id, // 访视ID
                  //    SubjectVisitName = y.VisitName, //  访视名称
                  //    Status = ReadingCommon.GetVisitSubmitStateEnum(y), // 状态
                  //    CreateTime = y.CreateTime, // 创建时间
                  //    SubjectCode = y.Subject.Code, // 受试者code
                  //    TrialSiteCode = x.TrialSite.TrialSiteCode, // 中心Code
                  //    VisitNum = y.VisitNum,
                  //    IsFinalVisit = y.IsFinalVisit, // 是否为末次评估
                  //    OutPlanPreviousVisitId = y.OutPlanPreviousVisitId, // 上一访视
                  //    OutPlanPreviousVisitName = y.OutPlanPreviousVisit.VisitName, // 上一访视名称
                  //    SiteId = x.Site.Id,  // 中心ID
                  //    IsVisit = true,  // 是否为访视
                  //    PDState = y.PDState, // PD 进展
                  //    IsEnrollmentConfirm = y.IsEnrollmentConfirm, // 入组
                  //    SubjectId = x.Id,
                  //}).ToList(),
                  //ReadModuleData = x.ReadModuleList.Select(
                  // z => new GetReadModuleOutDto()
                  // {
                  //     CreateTime = z.CreateTime,
                  //     Id = z.Id,
                  //     Name = z.ModuleName,
                  //     SubjectId = x.Id,
                  //     ModuleType = z.ModuleType,
                  //     Status = ReadingCommon.GetVisitSubmitStateEnum(z.SubjectVisit),
                  //     SubjectCode = x.Code,
                  //     TrialSiteCode = x.TrialSite.TrialSiteCode,
                  //     SubjectVisitId = z.SubjectVisitId,
                  //     SubjectVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
                  //     CutOffVisitId = z.SubjectVisitId,  // 截止访视
                  //     CutOffVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
                  //     ReadModuleId = z.ReadModuleId,
                  //     ReadModuleName = z.ReadModuleModel.ModuleName,
                  //     IsUrgent = z.IsUrgent
                  // }).ToList(),
              });
            var pageList = await subjectQuery.ToPagedListAsync(dto.PageIndex, dto.PageSize, dto.SortField == null || dto.SortField == string.Empty ? "SiteCode" : dto.SortField,
                dto.Asc);
            return (pageList, new
            {
                MaxLength = pageList.CurrentPageData.ToList().Count()
            });
        }
        /// 
        /// 获取读片模块
        /// 
        [HttpPost]
        public async Task<(PageOutput,object)> GetReadModuleList(GetReadModuleDto dto)
        {
            #region MyRegion
            var subjectQuery = _readModuleViewRepository.WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
            .WhereIf(dto.SubjectId != null, x => x.SubjectId == dto.SubjectId)
            .WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != String.Empty, x => x.TrialSiteCode == dto.TrialSiteCode)
            .WhereIf(dto.SubjectCode != null && dto.SubjectCode != String.Empty, x => x.SubjectCode == dto.SubjectCode)
            .WhereIf(dto.ModuleType != null, x => x.ModuleType == dto.ModuleType)
            .WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus)
            .WhereIf(dto.Name != null, x => x.Name.Contains(dto.Name)).OrderBy(x => x.SiteCode);
            var subjectIds = await subjectQuery.Select(x => x.SubjectId).Distinct().Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
            List ReadModuleViewList = await subjectQuery.Where(x => subjectIds.Contains(x.SubjectId)).ToListAsync();
            List getReadList = ReadModuleViewList.GroupBy(x => new { x.SubjectId, x.SiteId, x.TrialSiteCode, x.SubjectCode })
                .Select(x => new GetReadModuleDtoOut()
                {
                    TrialSiteCode = x.Key.TrialSiteCode,
                    SiteId = x.Key.SiteId,
                    SubjectCode = x.Key.SubjectCode,
                    SubjectId = x.Key.SubjectId,
                    Data = x.OrderBy(x=>x.ModuleType).ThenBy(x=>x.VisitNum).ToList(),
                }).ToList();
            PageOutput pageOutput = new PageOutput()
            {
                PageSize = dto.PageSize,
                CurrentPageData = getReadList,
                PageIndex = dto.PageIndex,
                TotalCount = await subjectQuery.Select(x => x.SubjectId).Distinct().CountAsync(),
            };
            var maxcount = 0;
            pageOutput.CurrentPageData.ForEach(x =>
            {
                maxcount = maxcount < x.Data.Count ? x.Data.Count : maxcount;
            });
            return (pageOutput, new
            {
                MaxLength = maxcount,
                IsClinicalReading = await _trialRepository.Where(x => x.Id == dto.TrialId).Select(x => x.IsClinicalReading).FirstOrDefaultAsync(),
                OnlyExistsMedicalHistory = !(await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataSetName != "既往局部治疗史" && x.IsConfirm))
            }) ;
            #endregion
            #region 用导航属性写的 有问题
            //var subjectQuery = _subjectRepository.WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
            //   .WhereIf(dto.SubjectId != null, x => x.Id == dto.SubjectId).Include(x => x.SubjectVisitList).Include(x => x.Site).Include(x => x.TrialSite)
            //   .WhereIf(dto.TrialSiteCode != null, x => x.TrialSite.TrialSiteCode == dto.TrialSiteCode)
            //   .WhereIf(dto.SubjectCode != null, x => x.Code == dto.SubjectCode)
            //  .Select(x => new GetReadModuleDtoOut
            //  {
            //      TrialSiteCode = x.TrialSite.TrialSiteCode,
            //      SiteCode = x.TrialSite.TrialSiteCode,
            //      SiteId = x.SiteId,
            //      SubjectCode = x.Code,
            //      SubjectId = x.Id,
            //      Data = x.SubjectVisitList.OrderByDescending(y => y.VisitNum).Select(y => new GetReadModuleOutDto()
            //      {
            //          Id = y.Id,  //id
            //          Name = y.VisitName,
            //          ModuleType = y.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit, // 模块类型
            //          IsUrgent = x.IsUrgent, // 是否加急
            //          SubjectVisitId = y.Id, // 访视ID
            //          SubjectVisitName = y.VisitName, //  访视名称
            //          Status = ReadingCommon.GetVisitSubmitStateEnum(y), // 状态
            //          CreateTime = y.CreateTime, // 创建时间
            //          SubjectCode = y.Subject.Code, // 受试者code
            //          TrialSiteCode = x.TrialSite.TrialSiteCode, // 中心Code
            //          VisitNum = y.VisitNum,
            //          IsFinalVisit = y.IsFinalVisit, // 是否为末次评估
            //          OutPlanPreviousVisitId = y.OutPlanPreviousVisitId, // 上一访视
            //          OutPlanPreviousVisitName = y.OutPlanPreviousVisit.VisitName, // 上一访视名称
            //          SiteId = x.Site.Id,  // 中心ID
            //          IsVisit = true,  // 是否为访视
            //          PDState = y.PDState, // PD 进展
            //          IsEnrollmentConfirm = y.IsEnrollmentConfirm, // 入组
            //          SubjectId = x.Id,
            //      }).ToList(),
            //      ReadModuleData = x.ReadModuleList.Select(
            //       z => new GetReadModuleOutDto()
            //       {
            //           CreateTime = z.CreateTime,
            //           Id = z.Id,
            //           Name = z.ModuleName,
            //           SubjectId = x.Id,
            //           ModuleType = z.ModuleType,
            //           Status = ReadingCommon.GetVisitSubmitStateEnum(z.SubjectVisit),
            //           SubjectCode = x.Code,
            //           TrialSiteCode = x.TrialSite.TrialSiteCode,
            //           SubjectVisitId = z.SubjectVisitId,
            //           SubjectVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
            //           CutOffVisitId = z.SubjectVisitId,  // 截止访视
            //           CutOffVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
            //           ReadModuleId = z.ReadModuleId,
            //           ReadModuleName = z.ReadModuleModel.ModuleName,
            //           IsUrgent = z.IsUrgent
            //       }).ToList(),
            //  });
            //if (dto.ModuleType != null)
            //{
            //    subjectQuery.
            //}
            //if (dto.Status != null)
            //{
            //    x.Data = x.Data.Where(y => y.Status == dto.Status).ToList();
            //}
            //if (dto.Name != null)
            //{
            //    x.Data = x.Data.Where(y => y.Name.Contains(y.Name)).ToList();
            //}
            //var pageList = await subjectQuery.ToPagedListAsync(dto.PageIndex, dto.PageSize, dto.SortField == null || dto.SortField == string.Empty ? "SiteCode" : dto.SortField,
            //    dto.Asc);
            //pageList.CurrentPageData.ForEach(x =>
            //{
            //    var outplan = x.Data.FirstOrDefault(x => x.IsFinalVisit);
            //    if (outplan != null)
            //    {
            //        x.Data = x.Data.Where(y => y.VisitNum >= outplan.VisitNum).ToList();
            //    }
            //});
            //var subjectIds = pageList.CurrentPageData.Select(x => x.SubjectId).ToList();
            //var readModules = await _readModuleRepository.Where(x => subjectIds.Contains(x.SubjectId)).Include(x => x.SubjectVisit)
            //    .Include(x => x.ReadModuleModel).ToListAsync();
            //return (pageList, new
            //{
            //    MaxLength = pageList.CurrentPageData.ToList().Max(x => x.Data.Count)
            //});
            #endregion
        }
        ///// 
        ///// 访视阅片完成添加阅片期模块
        ///// 
        ///// 
        //public async Task VisitFinishReadingAddReadModule(VisitFinishReadingAddReadModuleInDto inDto)
        //{
        //     var subjectVisit = await _subjectRepository.FirstOrDefaultNoTrackingAsync(x => x.Id == inDto.SubjectVisitId); 
        //     List readingPeriodSets= _readingPeriodSetRepository.Where(x=>x.TrialId==inDto.TrialId&&x.IsTakeEffect=&&(x.ReadingScope==ReadingScopeEnum.All||(x.ReadingScope==ReadingScopeEnum.Site&&x.ReadingPeriodSites.Select(y=>y.SiteId).Contains(subjectVisit.SiteId))))
        //}
        /// 
        /// 获取单条详情信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task GetReadModule(GetReadModuleSingleIndto dto)
        {
            var data = await GetReadModuleList(new GetReadModuleDto()
            {
                SubjectId = dto.SubjectId,
            });
            GetReadModuleSingleOutdto? readModule = data.Item1.CurrentPageData.FirstOrDefault().Data.Where(x => x.Id == dto.Id).Select(x => new GetReadModuleSingleOutdto()
            {
                Id = x.Id,
                ModuleType = x.ModuleType,
                SubjectVisitId = x.SubjectVisitId,
                SubjectVisitName = x.SubjectVisitName,
             
                Status = x.ReadingStatus,
            }).FirstOrDefault();
            var stakeholderIds = new List();
            var subjectVisit =await _subjectVisitRepository.FirstOrDefaultAsync(x => x.Id == readModule.SubjectVisitId);
            switch (readModule.Status)
            {
                case ReadingStatusEnum.ImageNotSubmit:
                    stakeholderIds.AddRange(await _dicomInstanceRepository.Where(x => x.SubjectVisitId == readModule.SubjectVisitId).Select(x => x.CreateUserId).Distinct().ToListAsync());
                    stakeholderIds.AddRange(await _noneDicomStudyFileRepository.Where(x => x.NoneDicomStudy.SubjectVisitId == readModule.SubjectVisitId).Select(x => x.CreateUserId).Distinct().ToListAsync());
                    break;
                case ReadingStatusEnum.ImageQuality:
                    if (subjectVisit.PreliminaryAuditUserId != null)
                    {
                        stakeholderIds.Add(subjectVisit.PreliminaryAuditUserId.Value);
                    }
                    if (subjectVisit.ReviewAuditUserId != null)
                    {
                        stakeholderIds.Add(subjectVisit.ReviewAuditUserId.Value);
                    }
                    break;
                case ReadingStatusEnum.TaskAllocate:
                    if (subjectVisit.CheckUserId != null)
                    {
                        stakeholderIds.Add(subjectVisit.CheckUserId.Value);
                    }
                  
                    break;
            };
            readModule.StakeholderIds = stakeholderIds.Distinct().ToList();
            readModule.StakeholderNames = await _userRepository.Where(x => readModule.StakeholderIds.Contains(x.Id)).Select(x => x.FirstName + "/" + x.LastName).ToListAsync();
            return readModule;
        }
        /// 
        /// 添加阅片的时候 获取访视
        /// 
        /// 
        /// 
        public async Task> GetSubjectReadVisitList(GetSubjectReadVisitsInDto inDto)
        {
            var maxReadVisit = await _readModuleRepository.Where(x => x.SubjectId == inDto.SubjectId&&x.ReadingSetType==inDto.ReadingSetType).OrderByDescending(x=>x.VisitNum).FirstOrDefaultAsync();
            var maxReadVisitNum= maxReadVisit==null?-1:maxReadVisit.VisitNum;
            var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null&&!x.IsLostVisit);
            var finalVisitNum = await visitQuery.Where(x => x.IsFinalVisit).Select(x => x.VisitNum).FirstOrDefaultAsync();
            var readModulequery = _readModuleRepository.AsQueryable();
           var resultlist= await visitQuery.WhereIf(finalVisitNum != null&& finalVisitNum!=0, x => x.VisitNum <= finalVisitNum)
                .Where(x=>x.VisitNum> maxReadVisitNum)
                .Where(x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == inDto.ReadingSetType).Count() == 0).OrderBy(x => finalVisitNum)
                .Select(x => new GetSubjectReadVisitsOutDto()
                {
                    SubjectVisitId = x.Id,
                    VisitName = x.VisitName,
                    VisitNum = x.VisitNum,
                }).ToListAsync();
            return resultlist;
        }
        /// 
        /// 添加阅片期
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task AddReadModule(ReadModuleAddDto dto)
        {
            var visitQuery =  _subjectVisitRepository.Where(x => x.SubjectId == dto.SubjectId);
            visitQuery = visitQuery
                //.WhereIf(dto.ExpirationDate != null, x => x.LatestScanDate <= dto.ExpirationDate.Value)
                .WhereIf(dto.ExpirationVisitNum != null, x => x.VisitNum == dto.ExpirationVisitNum.Value);
            var visit = visitQuery.OrderByDescending(x => x.VisitNum).FirstOrDefault();
            if (visit != null)
            {
                await _readModuleRepository.AddAsync(new ReadModule()
                {
                    Id= NewId.NextGuid(),
                    SubjectId = dto.SubjectId,
                    ModuleType = dto.ReadingSetType==ReadingSetType.ImageReading? ModuleTypeEnum.Read: ModuleTypeEnum.Oncology,
                    IsUrgent = visit.IsUrgent,
                    ModuleName = dto.Name,
                    SubjectVisitId = visit.Id,
                    ReadingSetType= dto.ReadingSetType,
                    TrialId= dto.TrialId,
                    VisitNum= visit.VisitNum,
                    ReadingStatus = ReadingStatusEnum.TaskAllocate,
                   
                });
                var res = await _readModuleRepository.SaveChangesAsync();
                return ResponseOutput.Ok(res);
            }
            else
            {
                return ResponseOutput.NotOk("No qualified visit was found ");
            }
          
        }
        ///// 
        ///// 新增或者修改
        ///// 
        ///// 
        ///// 
        //[HttpPost]
        //public async Task AddOrUpdateReadModuleService(ReadModuleAddOrEdit addOrEditReadModule)
        //{
        //    var entity = await _repository.InsertOrUpdateAsync(addOrEditReadModule, true);
        //    return ResponseOutput.Ok(entity.Id.ToString());
        //}
        /// 
        /// 删除
        /// 
        /// 
        /// 
        [HttpDelete("{readModuleId:guid}")]
        public async Task DeleteReadModule(Guid readModuleId)
        {
            await _readModuleRepository.DeleteFromQueryAsync(t => t.Id == readModuleId, true);
            return ResponseOutput.Result(true);
        }
    }
}