//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-08-12 14:07:20 
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Service
{
    /// 
    /// 器官服务层
    /// 	
    [ApiExplorerSettings(GroupName = "Reading")]
    public class OrganInfoService(IRepository _organInfoRepository,
        IRepository _dictionaryRepository,
        IRepository _visitTaskRepository,
        IRepository _organTrialInfoRepository,
        IRepository _readingQuestionCriterionTrial,
        IRepository _criterionNidusRepository,
        IRepository _criterionNidusTrialRepository,
        IRepository _readingQuestionCriterionSystemRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IOrganInfoService
    {
        #region 系统器官
        /// 
        /// 获取系统器官信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetOrganInfoList(OrganInfoQuery inQuery)
        {
            List organs = new List();
            if (inQuery.LesionType != null)
            {
                organs = await _criterionNidusRepository.Where(x => x.CriterionId == inQuery.SystemCriterionId && x.LesionType == inQuery.LesionType)
                    .Select(x => x.OrganType).ToListAsync();
            }
            var organInfoQueryable = _organInfoRepository
               .Where(x => x.SystemCriterionId == inQuery.SystemCriterionId)
               .WhereIf(inQuery.LesionType != null, x => organs.Contains(x.OrganType))
                 .WhereIf(inQuery.OrganType != null, x => x.OrganType == inQuery.OrganType)
                 .OrderBy(x => x.OrganType)
                 .ThenBy(x => x.ShowOrder)
               .ProjectTo(_mapper.ConfigurationProvider);
            return await organInfoQueryable.ToListAsync();
        }
        /// 
        /// 获取系统器官分页信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetOrganPageList(OrganInfoQuery inQuery)
        {
            List organs = new List();
            if (inQuery.LesionType != null)
            {
                organs = await _criterionNidusRepository.Where(x => x.CriterionId == inQuery.SystemCriterionId && x.LesionType == inQuery.LesionType)
                    .Select(x => x.OrganType).ToListAsync();
            }
            var organInfoQueryable = _organInfoRepository
               .Where(x => x.SystemCriterionId == inQuery.SystemCriterionId)
                  .WhereIf(!inQuery.Part.IsNullOrEmpty(), x => x.Part.Contains(inQuery.Part))
                   .WhereIf(!inQuery.TULOC.IsNullOrEmpty(), x => x.TULOC.Contains(inQuery.TULOC))
                    .WhereIf(!inQuery.TULAT.IsNullOrEmpty(), x => x.TULAT.Contains(inQuery.TULAT))
               .WhereIf(inQuery.LesionType != null, x => organs.Contains(x.OrganType))
                 .WhereIf(inQuery.OrganType != null, x => x.OrganType == inQuery.OrganType)
               .ProjectTo(_mapper.ConfigurationProvider);
            return await organInfoQueryable.ToPagedListAsync(inQuery, new string[] { nameof(OrganInfoView.OrganType), nameof(OrganInfoView.ShowOrder) });
        }
        /// 
        /// 新增或修改系统器官数据
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task AddOrUpdateOrganInfo(OrganInfoAddOrEdit addOrEditOrganInfo)
        {
            var entity = await _organInfoRepository.InsertOrUpdateAsync(addOrEditOrganInfo, true);
            return ResponseOutput.Ok(entity.Id.ToString());
        }
        /// 
        /// 删除系统器官
        /// 
        /// 
        /// 
        [HttpDelete("{Id:guid}")]
        public async Task DeleteOrganInfo(Guid Id)
        {
            var success = await _organInfoRepository.DeleteFromQueryAsync(t => t.Id == Id, true);
            return ResponseOutput.Ok();
        }
        #endregion
        /// 
        /// 获取阅片器官信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetReadingOrganList(GetReadingOrganListInDto inDto)
        {
            var trialReadingCriterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync();
            var isEn = _userInfo.IsEn_Us;
            var organInfoQueryable = from data in _organInfoRepository.AsQueryable()
                                     join trialData in _organTrialInfoRepository.AsQueryable().Where(x => x.IsEnable && x.TrialCriterionId == trialReadingCriterionId)
                                     on data.Id equals trialData.OrganInfoId
                                     join criterionNidus in _criterionNidusTrialRepository.AsQueryable().Where(x => x.CriterionId == trialReadingCriterionId)
                                     on data.OrganType equals criterionNidus.OrganType
                                     select new ReadingOrganDto()
                                     {
                                         Id = trialData.Id,
                                         OrganInfoId = data.Id,
                                         Part = isEn ? data.PartEN : data.Part,
                                         TULAT = isEn ? data.TULATEN : data.TULAT,
                                         ShowOrder = data.ShowOrder,
                                         Classification = isEn ? data.ClassificationEN : data.Classification,
                                         ClassificationEN = data.ClassificationEN,
                                         TULOC = isEn ? data.TULOCEN : data.TULOC,
                                         Remark = data.Remark,
                                         IsLymphNodes = data.IsLymphNodes,
                                         IsCanEditPosition = data.IsCanEditPosition,
                                         IsEnable = trialData.IsEnable,
                                         OrganType = data.OrganType,
                                         PartEN = data.PartEN,
                                         TULATEN = data.TULATEN,
                                         TULOCEN = data.TULOCEN,
                                         LesionType = criterionNidus.LesionType
                                     };
            var organList = await organInfoQueryable.ToListAsync();
            List result = organList.GroupBy(x => new { x.LesionType }).Select(x => new GetReadingOrganListOutDto()
            {
                LesionType = x.Key.LesionType,
                OrganList = x.OrderBy(y => y.ShowOrder).ToList()
            }).ToList();
            return result;
        }
        #region 项目器官
        /// 
        /// 获取项目器官信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetTrialOrganList(GetTrialOrganListInDto inDto)
        {
            List organs = new List();
            if (inDto.TrialReadingCriterionId == null)
            {
                inDto.TrialReadingCriterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync();
            }
            if (inDto.LesionType != null)
            {
                var criterion = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
                organs = await _criterionNidusTrialRepository.Where(x => x.CriterionId == (criterion == null ? default(Guid) : criterion.Id) && x.LesionType == inDto.LesionType)
                    .Select(x => x.OrganType).ToListAsync();
            }
            var organInfoQueryable = from data in _organInfoRepository
                                                 .WhereIf(inDto.OrganType != null, x => x.OrganType == inDto.OrganType)
                                                 .WhereIf(inDto.IsLymphNodes != null, x => x.IsLymphNodes == inDto.IsLymphNodes)
                                                  .WhereIf(inDto.LesionType != null, x => organs.Contains(x.OrganType))
                                                   .WhereIf(!inDto.Part.IsNullOrEmpty(), x => x.Part.Contains(inDto.Part) || x.PartEN.Contains(inDto.Part))
                                                    .WhereIf(!inDto.TULOC.IsNullOrEmpty(), x => x.TULOC.Contains(inDto.TULOC) || x.TULOCEN.Contains(inDto.TULOC))
                                                     .WhereIf(!inDto.TULAT.IsNullOrEmpty(), x => x.TULAT.Contains(inDto.TULAT) || x.TULATEN.Contains(inDto.TULAT))
                                     join trialData in _organTrialInfoRepository.WhereIf(inDto.IsEnable != null, x => x.IsEnable == inDto.IsEnable)
                                                 .WhereIf(inDto.IsEnable != null, x => x.IsEnable == inDto.IsEnable)
                                                 .Where(x => x.TrialCriterionId == inDto.TrialReadingCriterionId)
                                     on data.Id equals trialData.OrganInfoId
                                     select new GetTrialOrganListOutDto()
                                     {
                                         Id = trialData.Id,
                                         Part = data.Part,
                                         TULAT = data.TULAT,
                                         TULOC = data.TULOC,
                                         Remark = data.Remark,
                                         ShowOrder = data.ShowOrder,
                                         Classification = data.Classification,
                                         ClassificationEN = data.ClassificationEN,
                                         IsLymphNodes = data.IsLymphNodes,
                                         IsCanEditPosition = data.IsCanEditPosition,
                                         IsEnable = trialData.IsEnable,
                                         OrganType = data.OrganType,
                                         PartEN = data.PartEN,
                                         TULATEN = data.TULATEN,
                                         TULOCEN = data.TULOCEN,
                                     };
            return await organInfoQueryable.OrderBy(x => x.OrganType).ThenBy(x => x.ShowOrder).ToListAsync();
        }
        /// 
        /// 批量添加项目器官
        /// 
        /// 
        /// 
        public async Task BatchAddTrialOrgan(BatchAddTrialOrganInDto inDto)
        {
            //await _organTrialInfoRepository.BatchDeleteNoTrackingAsync(t => t.TrialId==inDto.TrialId&&t.OrganType == inDto.OrganType);
            List organTrialInfos = inDto.OrganIds.Select(x => new OrganTrialInfo()
            {
                OrganInfoId = x,
                TrialId = inDto.TrialId,
                TrialCriterionId = inDto.TrialReadingCriterionId,
                //OrganType=inDto.OrganType,
            }).ToList();
            await _organTrialInfoRepository.AddRangeAsync(organTrialInfos);
            await _organInfoRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }
        /// 
        /// 删除系统器官
        /// 
        /// 
        /// 
        [HttpDelete("{Id:guid}")]
        public async Task DeleteTrialOrganInfo(Guid Id)
        {
            var success = await _organTrialInfoRepository.DeleteFromQueryAsync(t => t.Id == Id, true);
            return ResponseOutput.Ok();
        }
        /// 
        /// 设置项目器官是否生效
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task SetOrganIsEnable(SetOrganIsEnableInDto inDto)
        {
            await _organTrialInfoRepository.UpdatePartialFromQueryAsync(x => inDto.Ids.Contains(x.Id), x => new OrganTrialInfo()
            {
                IsEnable = inDto.IsEnable
            });
            await _organTrialInfoRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }
        #endregion
        #region 器官和病灶绑定表 (项目和系统 在同一张表)  
        /// 
        /// 获取标准病灶类型
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetCriterionLesionType(GetCriterionLesionTypeInDto inDto)
        {
            var dicNums = new List();
            if (inDto.TrialCriterionId != null)
            {
                dicNums = await _criterionNidusTrialRepository.Where(x => x.CriterionId == inDto.TrialCriterionId).Select(x => ((int)x.LesionType).ToString()).Distinct().ToListAsync();
            }
            else
            {
                dicNums = await _criterionNidusRepository.Where(x => x.CriterionId == inDto.SystemCriterionId).Select(x => ((int)x.LesionType).ToString()).Distinct().ToListAsync();
            }
            var dictionaryId = await _dictionaryRepository.Where(x => x.Code == "LesionType").Select(x => x.Id).FirstOrDefaultAsync();
            var result = await _dictionaryRepository.Where(x => x.ParentId == dictionaryId && dicNums.Contains(x.Code)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
            return result;
        }
        /// 
        /// 获取标准病灶器官关系信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task> GetCriterionNidusList(CriterionNidusQuery inQuery)
        {
            if (await _readingQuestionCriterionSystemRepository.AnyAsync(x => x.Id == inQuery.CriterionId))
            {
                return await _criterionNidusRepository
               .Where(x => x.CriterionId == inQuery.CriterionId)
               .ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
            }
            else
            {
                return await _criterionNidusTrialRepository
             .Where(x => x.CriterionId == inQuery.CriterionId)
             .ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
            }
        }
        /// 
        /// 新增修改标准病灶器官关系信息
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task AddOrUpdateCriterionNidus(CriterionNidusAddOrEdit inDto)
        {
            if (await _criterionNidusRepository.AnyAsync(x => x.OrganType == inDto.OrganType && x.LesionType == inDto.LesionType && x.CriterionId == inDto.CriterionId && x.Id != inDto.Id))
            {
                //---存在相同的数据,操作失败
                throw new BusinessValidationFailedException(_localizer["OrganInfo_DuplicateData"]);
            }
            var entity = await _criterionNidusRepository.InsertOrUpdateAsync(inDto, true);
            return ResponseOutput.Ok(entity.Id.ToString());
        }
        /// 
        /// 删除病灶病灶器官关系信息
        /// 
        /// 
        /// 
        [HttpDelete("{id:guid}")]
        public async Task DeleteCriterionNidus(Guid id)
        {
            var success = await _criterionNidusRepository.DeleteFromQueryAsync(t => t.Id == id, true);
            return ResponseOutput.Ok();
        }
        #endregion
        /// 
        /// 同步系统器官
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task SynchronizeSystemOrgan(SynchronizeSystemOrganInDto inDto)
        {
            var organList = await _organInfoRepository.Where(x => x.SystemCriterionId == inDto.FromCriterionId).ToListAsync();
            organList.ForEach(x =>
            {
                x.SystemCriterionId = inDto.ToCriterionId;
                x.Id = NewId.NextGuid();
            });
            await _organInfoRepository.BatchDeleteNoTrackingAsync(x => x.SystemCriterionId == inDto.ToCriterionId);
            await _organInfoRepository.AddRangeAsync(organList);
            await _organInfoRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }
        /// 
        /// 同步系统器官到项目
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task SynchronizeSystemOrganToTrial(SynchronizeSystemOrganToTrialInDto inDto)
        {
            // 选中的标准进行修改
            var readingQuestionCriterionTrial = await _readingQuestionCriterionTrial.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
            if (readingQuestionCriterionTrial != null)
            {
                Guid trialCriterionId = default(Guid);
                trialCriterionId = readingQuestionCriterionTrial.Id;
                if (inDto.SystemCriterionId == null)
                {
                    inDto.SystemCriterionId = readingQuestionCriterionTrial.ReadingQuestionCriterionSystemId;
                }
                await _criterionNidusTrialRepository.BatchDeleteNoTrackingAsync(x => x.CriterionId == trialCriterionId);
                List criterionNidusList = await _criterionNidusRepository.Where(x => x.CriterionId == inDto.SystemCriterionId).Select(x => new CriterionNidusTrial()
                {
                    Id = x.Id,
                    CriterionId = trialCriterionId,
                    LesionType = x.LesionType,
                    OrganType = x.OrganType,
                }).ToListAsync();
                criterionNidusList.ForEach(x => x.Id = NewId.NextGuid());
                await _criterionNidusTrialRepository.AddRangeAsync(criterionNidusList);
                await _organTrialInfoRepository.BatchDeleteNoTrackingAsync(x => x.TrialCriterionId == readingQuestionCriterionTrial.Id);
                List organTrialInfoList = await _organInfoRepository.Where(x => x.SystemCriterionId == inDto.SystemCriterionId).Select(x => new OrganTrialInfo()
                {
                    //OrganType=x.OrganType,
                    Id = x.Id,
                    IsEnable = true,
                    TrialCriterionId = readingQuestionCriterionTrial.Id,
                    OrganInfoId = x.Id,
                    TrialId = readingQuestionCriterionTrial.TrialId,
                    TULAT = x.TULAT,
                    Classification = x.Classification,
                    ClassificationEN = x.ClassificationEN,
                    IsCanEditPosition = x.IsCanEditPosition,
                    Part = x.Part,
                    IsLymphNodes = x.IsLymphNodes,
                    PartEN = x.PartEN,
                    ShowOrder = x.ShowOrder,
                    TULATEN = x.TULATEN,
                    TULOC = x.TULOC,
                    TULOCEN = x.TULOCEN,
                    OrganType = x.OrganType,
                }).ToListAsync();
                organTrialInfoList.ForEach(x => x.Id = NewId.NextGuid());
                await _organTrialInfoRepository.AddRangeAsync(organTrialInfoList);
                await _organTrialInfoRepository.SaveChangesAsync();
            }
            return ResponseOutput.Ok();
        }
        #region 注释
        ///// 
        ///// 获取项目勾选器官信息
        ///// 
        ///// 
        ///// 
        //[HttpPost]
        //public async Task> GetTrialCheckOrganList(GetTrialOrganListInDto inDto)
        //{
        //    var organInfoQueryable = from data in _organInfoRepository.WhereIf(inDto.CriterionNidusId != null, x => x.CriterionNidusId == inDto.CriterionNidusId)
        //                             join trialData in _organTrialInfoRepository.WhereIf(inDto.IsEnable != null, x => x.IsEnable == inDto.IsEnable)
        //                             .Where(x => x.TrialId == inDto.TrialId)
        //                             on data.Id equals trialData.OrganInfoId into jtemp
        //                             from leftjoin in jtemp.DefaultIfEmpty()
        //                             select new GetTrialCheckOrganList()
        //                             {
        //                                 Id = data.Id,
        //                                 Part = data.Part,
        //                                 TULAT = data.TULAT,
        //                                 TULOC = data.TULOC,
        //                                 IsCheckd= leftjoin!=null,
        //                                 Remark = data.Remark,
        //                                 CriterionNidusId = data.CriterionNidusId,
        //                                 IsEnable = leftjoin.IsEnable,
        //                             };
        //    return await organInfoQueryable.ToListAsync();
        //}
        #endregion
    }
}