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;

namespace IRaCIS.Application.Services
{
    /// <summary>
    /// 临床数据配置
    /// </summary>
    [ApiExplorerSettings(GroupName = "Reading")]
    public class ClinicalDataSetService : BaseService
    {

        public IRepository<SubjectVisit> _subjectVisitRepository;
       
        private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
        private readonly IRepository<ClinicalDataSystemSet> _clinicalDataSystemSetRepository;
        private readonly IRepository<PreviousPDF> _previousPDFRepository;
        private readonly IRepository<Trial> _trialRepository;

        public ClinicalDataSetService(IRepository<SubjectVisit> subjectVisitRepository,
         
            IRepository<ClinicalDataTrialSet> ClinicalDataTrialSetRepository,
            IRepository<ClinicalDataSystemSet> ClinicalDataSystemSetRepository,
            IRepository<PreviousPDF> previousPDFRepository,
            IRepository<Trial> trialRepository
          )
        {
            _subjectVisitRepository = subjectVisitRepository;
          
            _clinicalDataTrialSetRepository = ClinicalDataTrialSetRepository;
            _clinicalDataSystemSetRepository = ClinicalDataSystemSetRepository;
            this._previousPDFRepository = previousPDFRepository;
            this._trialRepository = trialRepository;
        }


        /// <summary>
        /// 新增或者修改(项目)
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateClinicalDataTrialSet(ClinicalDataTrialSetAddOrEdit indto)
        {
            var existsQuery = _clinicalDataTrialSetRepository
             .WhereIf(indto.Id != null, x => x.Id != indto.Id)
             .Where(x => x.ClinicalDataSetName == indto.ClinicalDataSetName&&x.TrialId==indto.TrialId);

            if (await existsQuery.AnyAsync())
            {
                return ResponseOutput.NotOk("存在同类型的临床数据,操作失败");
            }
            var entity = await _clinicalDataTrialSetRepository.InsertOrUpdateAsync(indto,true);
            return ResponseOutput.Ok(entity.Id.ToString());
        }

        /// <summary>
        /// 新增或者修改(系统)
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateClinicalDataSystemSet(ClinicalDataSystemSetAddOrEdit indto)
        {

            var existsQuery = _clinicalDataSystemSetRepository
              .WhereIf(indto.Id != null, x => x.Id != indto.Id)
              .Where(x => x.ClinicalDataSetName == indto.ClinicalDataSetName);

            if (await existsQuery.AnyAsync())
            {
                return ResponseOutput.NotOk("存在同类型的临床数据,操作失败");
            }
            var entity = await _clinicalDataSystemSetRepository.InsertOrUpdateAsync(indto, true);
            return ResponseOutput.Ok(entity.Id.ToString());
        }

        /// <summary>
        /// 获取系统临床数据(系统)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ClinicalDataSystemSetView>> GetSystemClinicalDataSystemSetList(GetTrialClinicalDataSystemIndto inDto)
        {
            return await _clinicalDataSystemSetRepository.AsQueryable()
                 .WhereIf(inDto.ClinicalDataLevel != null, x => x.ClinicalDataLevel == inDto.ClinicalDataLevel)
                .WhereIf(inDto.ClinicalUploadType != null, x => x.ClinicalUploadType == inDto.ClinicalUploadType)
                 .WhereIf(inDto.ClinicalDataSetName != String.Empty, x => x.ClinicalDataSetName.Contains(inDto.ClinicalDataSetName))

             .ProjectTo<ClinicalDataSystemSetView>(_mapper.ConfigurationProvider).ToListAsync();
        }


        /// <summary>
        /// 获取项目的临床数据
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<ClinicalDataTrialSetView>> GetTrialClinicalDataTrialSetList(GetTrialClinicalDataTrialIndto inDto)
        {
            await this.AddTrialClinicalDataTrialSet(inDto.TrialId);
            var trialClinicalDataList= await _clinicalDataTrialSetRepository.AsQueryable()
               .Where(x => x.TrialId == inDto.TrialId)
               .WhereIf(inDto.ClinicalDataLevel!=null,x=>x.ClinicalDataLevel== inDto.ClinicalDataLevel)
                .WhereIf(inDto.ClinicalUploadType != null, x => x.ClinicalUploadType == inDto.ClinicalUploadType)
                 .WhereIf(inDto.ClinicalDataSetName != String.Empty, x => x.ClinicalDataSetName.Contains(inDto.ClinicalDataSetName))
               .ProjectTo<ClinicalDataTrialSetView>(_mapper.ConfigurationProvider).ToListAsync();
            return trialClinicalDataList;

        }



        /// <summary>
        /// 将系统配置添加到项目配置
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>

        private async Task AddTrialClinicalDataTrialSet(Guid trialId)
        {
            var syncClinicalDataTime = await _trialRepository.Where(x => x.Id == trialId).Select(x => x.SyncClinicalDataTime).FirstOrDefaultAsync();
            if (syncClinicalDataTime == null)
            {
                var systemClinicalDataList = await _clinicalDataSystemSetRepository.AsQueryable().ToListAsync();
                var systemIds = systemClinicalDataList.Select(x => x.Id).ToList();
                var trialSystemIds = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == trialId && x.SystemClinicalDataSetId != null).Select(x => x.SystemClinicalDataSetId.Value).ToListAsync();
                //var needUpdateIds = systemIds.Intersect(trialSystemIds).ToList();

                var needAddids = systemIds.Except(trialSystemIds).ToList();
                var systemDataList = systemClinicalDataList.Where(x => needAddids.Contains(x.Id)).ToList();
                List<ClinicalDataTrialSet> dataSets = systemDataList.Select(x => new ClinicalDataTrialSet()
                {
                    Id = NewId.NextGuid(),
                    SystemClinicalDataSetId = x.Id,
                    ClinicalDataSetName = x.ClinicalDataSetName,
                    ClinicalDataLevel = x.ClinicalDataLevel,
                    ClinicalUploadType = x.ClinicalUploadType,
                    UploadRole = x.UploadRole,
                    FileName = x.FileName,
                    Path = x.Path,
                    TrialId = trialId,

                }).ToList();

                await _clinicalDataTrialSetRepository.AddRangeAsync(dataSets);

                //var needUpdateitemList = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == trialId && needUpdateIds.Contains(x.SystemClinicalDataSetId.Value)).ToListAsync();
                //foreach (var item in needUpdateitemList)
                //{
                //   var systemData = systemClinicalDataList.FirstOrDefault(x => x.Id == item.SystemClinicalDataSetId);
                //   await _clinicalDataTrialSetRepository.UpdatePartialNoQueryAsync(item.Id,x=>new ClinicalDataTrialSet() {

                //       ClinicalDataSetName = systemData.ClinicalDataSetName,
                //       ClinicalDataLevel = systemData.ClinicalDataLevel,
                //       ClinicalUploadType = systemData.ClinicalUploadType,
                //       UploadRole = systemData.UploadRole,
                //       FileName = systemData.FileName,
                //       Path = systemData.Path,
                //   });
                //}

                await _trialRepository.BatchUpdateNoTrackingAsync(x => x.Id == trialId, x => new Trial()
                {
                    SyncClinicalDataTime = DateTime.Now,
                });
                var result = await _clinicalDataTrialSetRepository.SaveChangesAsync();
               
            }

        }

        /// <summary>
        /// 删除(项目)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:guid}")]
        public async Task<IResponseOutput> DeleteClinicalTrialSetData(Guid id)
        {
           await _clinicalDataTrialSetRepository.DeleteFromQueryAsync(x=>x.Id== id,true);
            return ResponseOutput.Result(true);
        }

        /// <summary>
        /// 删除(系统)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:guid}")]
        public async Task<IResponseOutput> DeleteClinicalSystemSetData(Guid id)
        {
            await _clinicalDataSystemSetRepository.DeleteFromQueryAsync(x => x.Id == id, true);
            return ResponseOutput.Result(true);
        }
    }
}