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

using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infra.EFCore.Common;
using MassTransit;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Share;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 器官服务层
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Reading")]
    public class OrganInfoService : BaseService, IOrganInfoService
    {

        private readonly IRepository<OrganInfo> _organInfoRepository;
        private readonly IRepository<Dictionary> _dictionaryRepository;
        private readonly IRepository<OrganTrialInfo> _organTrialInfoRepository;
        private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
        private readonly IRepository<CriterionNidus> _criterionNidusRepository;

        public OrganInfoService(
            IRepository<OrganInfo> organInfoRepository,
            IRepository<Dictionary> dictionaryRepository,
          
            IRepository<OrganTrialInfo> organTrialInfoRepository,
            IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial,
            IRepository<CriterionNidus> criterionNidusRepository
            )
        {
            _organInfoRepository = organInfoRepository;
            this._dictionaryRepository = dictionaryRepository;
            this._organTrialInfoRepository = organTrialInfoRepository;
            this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
            this._criterionNidusRepository = criterionNidusRepository;
        }

        /// <summary>
        /// 获取标准病灶类型
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<OrganDictionary>> GetCriterionLesionType(GetCriterionLesionTypeInDto inDto)
        {
            var dicNums = new List<string>();
            dicNums = await _criterionNidusRepository.Where(x => x.CriterionId == inDto.CriterionId).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<OrganDictionary>(_mapper.ConfigurationProvider).ToListAsync();

            return result;
        }

        /// <summary>
        /// 获取标准病灶器官关系信息
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<CriterionNidusView>> GetCriterionNidusList(CriterionNidusQuery inQuery)
        {

            var criterionNidusQueryable = _criterionNidusRepository
                .Where(x=>x.CriterionId== inQuery.CriterionId)
            .ProjectTo<CriterionNidusView>(_mapper.ConfigurationProvider);

            return await criterionNidusQueryable.ToListAsync();
        }

        /// <summary>
        /// 新增修改标准病灶器官关系信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> 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("存在相同的数据,操作失败");
            }
            var entity = await _criterionNidusRepository.InsertOrUpdateAsync(inDto, true);

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

        }

        /// <summary>
        /// 删除病灶病灶器官关系信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:guid}")]
        public async Task<IResponseOutput> DeleteCriterionNidus(Guid id)
        {
            var success = await _criterionNidusRepository.DeleteFromQueryAsync(t => t.Id == id, true);
            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 获取系统器官信息
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<OrganInfoView>> GetOrganInfoList(OrganInfoQuery inQuery)
        {
            List<OrganType> organs = new List<OrganType>();
            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)
               .ProjectTo<OrganInfoView>(_mapper.ConfigurationProvider);
            return await organInfoQueryable.ToListAsync();
        }


        /// <summary>
        /// 获取系统器官分页信息
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<OrganInfoView>> GetOrganPageList(OrganInfoQuery inQuery)
        {


            List<OrganType> organs = new List<OrganType>();

            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)
               .ProjectTo<OrganInfoView>(_mapper.ConfigurationProvider);
            return await organInfoQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(OrganInfoView.OrganType) : inQuery.SortField, inQuery.Asc);
        }

        /// <summary>
        /// 新增或修改系统器官数据
        /// </summary>
        /// <param name="addOrEditOrganInfo"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateOrganInfo(OrganInfoAddOrEdit addOrEditOrganInfo)
        {
            var entity = await _organInfoRepository.InsertOrUpdateAsync(addOrEditOrganInfo, true);
            return ResponseOutput.Ok(entity.Id.ToString());
        }


        /// <summary>
        /// 删除系统器官
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete("{Id:guid}")]
        public async Task<IResponseOutput> DeleteOrganInfo(Guid Id)
        {
            var success = await _organInfoRepository.DeleteFromQueryAsync(t => t.Id == Id, true);
            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 批量添加项目器官
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> BatchAddTrialOrgan(BatchAddTrialOrganInDto inDto)
        {
            //await _organTrialInfoRepository.BatchDeleteNoTrackingAsync(t => t.TrialId==inDto.TrialId&&t.OrganType == inDto.OrganType);

            List<OrganTrialInfo> organTrialInfos = inDto.OrganIds.Select(x => new OrganTrialInfo()
            {
                OrganInfoId=x,
                TrialId=inDto.TrialId,
                //OrganType=inDto.OrganType,
            }).ToList();


            await _organTrialInfoRepository.AddRangeAsync(organTrialInfos);

            await _organInfoRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 删除系统器官
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete("{Id:guid}")]
        public async Task<IResponseOutput> DeleteTrialOrganInfo(Guid Id)
        {
            var success = await _organTrialInfoRepository.DeleteFromQueryAsync(t => t.Id == Id, true);
            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 获取项目器官信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialOrganListOutDto>> GetTrialOrganList(GetTrialOrganListInDto inDto)
        {

            List<OrganType> organs = new List<OrganType>();

            if (inDto.LesionType != null)
            {
                var criterion = await _readingQuestionCriterionTrial.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm).FirstOrDefaultAsync();
                organs = await _criterionNidusRepository.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))
                                     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.TrialId == inDto.TrialId)
                                     on data.Id equals trialData.OrganInfoId
                                     select new GetTrialOrganListOutDto()
                                     {
                                         Id = trialData.Id,
                                         Part = data.Part,
                                         TULAT = data.TULAT,
                                         TULOC = data.TULOC,
                                         Remark= data.Remark,
                                         IsLymphNodes = data.IsLymphNodes,
                                         IsCanEditPosition=data.IsCanEditPosition,
                                         IsEnable = trialData.IsEnable,
                                         OrganType = data.OrganType,
                                     };


            return await organInfoQueryable.ToListAsync();
        }


        #region 注释
        ///// <summary>
        ///// 获取项目勾选器官信息
        ///// </summary>
        ///// <param name="inDto"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public async Task<List<GetTrialCheckOrganList>> 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


        /// <summary>
        /// 同步系统器官到项目
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SynchronizeSystemOrganToTrial(SynchronizeSystemOrganToTrialInDto inDto)
        {
            // 选中的标准进行修改
            var readingQuestionCriterionTrial = await _readingQuestionCriterionTrial.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm).FirstOrDefaultAsync();

            if (readingQuestionCriterionTrial != null)
            {
                Guid trialCriterionId = default(Guid);

                trialCriterionId = readingQuestionCriterionTrial.Id;
                if (inDto.SystemCriterionId == null)
                {
                    inDto.SystemCriterionId = readingQuestionCriterionTrial.ReadingQuestionCriterionSystemId;
                }
                await _criterionNidusRepository.BatchDeleteNoTrackingAsync(x => x.CriterionId == trialCriterionId);
                List<CriterionNidusData> criterionNidusList = await _criterionNidusRepository.Where(x => x.CriterionId == inDto.SystemCriterionId).Select(x => new CriterionNidusData()
                {
                    Id = x.Id,
                    CriterionId = trialCriterionId,
                    LesionType = x.LesionType,
                    OriginalId = x.Id,
                    OrganType=x.OrganType,
                    IsSystemCriterion=false,
                }).ToListAsync();

                criterionNidusList.ForEach(x => x.Id = NewId.NextGuid());

                await _criterionNidusRepository.AddRangeAsync(criterionNidusList);
                await _organTrialInfoRepository.BatchDeleteNoTrackingAsync(x => x.TrialId == inDto.TrialId);
                var originalIds = criterionNidusList.Select(x => x.OriginalId).Distinct().ToList();
                List<OrganTrialInfo> 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 = inDto.TrialId,
                }).ToListAsync();

                organTrialInfoList.ForEach(x => x.Id = NewId.NextGuid());
                await _organTrialInfoRepository.AddRangeAsync(organTrialInfoList);
                await _readingQuestionCriterionTrial.BatchUpdateNoTrackingAsync(x=>x.Id==trialCriterionId,x=> new ReadingQuestionCriterionTrial() { 
                SynchronizeOriginalTime=DateTime.Now
                });
                await _organTrialInfoRepository.SaveChangesAsync();
            }

          

            return ResponseOutput.Ok();

        }


      

        /// <summary>
        /// 设置项目器官是否生效
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SetOrganIsEnable(SetOrganIsEnableInDto inDto)
        {
            await _organTrialInfoRepository.UpdatePartialFromQueryAsync(x => inDto.Ids.Contains(x.Id), x => new OrganTrialInfo()
            {
                IsEnable=inDto.IsEnable
            });

            await _organTrialInfoRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }

    }
}