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 IRaCIS.Core.Domain.Share.Reading;
using MassTransit;

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

        public IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<ClinicalData> _clinicalDataRepository;
        private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
        private readonly IRepository<ClinicalDataSystemSet> _clinicalDataSystemSetRepository;
        private readonly IRepository<PreviousPDF> _previousPDFRepository;

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


        /// <summary>
        /// 新增或者修改(项目)
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateClinicalDataTrialSet(ClinicalDataTrialSetAddOrEdit indto)
        {
            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 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);
            return 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();

        }


        /// <summary>
        /// 设置勾选
        /// </summary>
        /// <param name="setClinicalData"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> SetClinicalDataCheckd(SetClinicalDataCheckdIndto setClinicalData)
        {
            // 为了后面稽查这样写

            var nocheckids =await _clinicalDataTrialSetRepository.Where(x => x.TrialId == setClinicalData.TrialId && setClinicalData.ClinicalDataTrialIds.Contains(x.Id)).Select(x => x.Id).ToListAsync();

            foreach (var item in setClinicalData.ClinicalDataTrialIds)
            {
              
          
                    await _clinicalDataTrialSetRepository.UpdatePartialFromQueryAsync(item, x => new ClinicalDataTrialSet()
                    {
                        IsCheck = true
                    }); 
               
            }

            foreach (var item in nocheckids)
            {


                await _clinicalDataTrialSetRepository.UpdatePartialFromQueryAsync(item, x => new ClinicalDataTrialSet()
                {
                    IsCheck = false
                });

            }

            await _clinicalDataTrialSetRepository.SaveChangesAsync();

            return ResponseOutput.Ok(true);
        }

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

        private async Task<IResponseOutput> AddTrialClinicalDataTrialSet(Guid trialId)
        {
            var systemIds = await _clinicalDataSystemSetRepository.Select(x => x.Id).ToListAsync();
            var trialSystemIds =await _clinicalDataTrialSetRepository.Where(x => x.TrialId == trialId && x.SystemClinicalDataSetId != null).Select(x => x.SystemClinicalDataSetId.Value).ToListAsync();
            var needAddids  = systemIds.Except(trialSystemIds).ToList();
            var systemDataList =await _clinicalDataSystemSetRepository.Where(x => needAddids.Contains(x.Id)).ToListAsync();
            List<ClinicalDataTrialSet> dataSets = systemDataList.Select(x => new ClinicalDataTrialSet()
            {
                Id= NewId.NextGuid(),
                SystemClinicalDataSetId=x.Id,
                ClinicalDataSetName=x.ClinicalDataSetName,
                ClinicalDataLevel=x.ClinicalDataLevel,
                ClinicalUploadType=x.ClinicalUploadType,
                TrialId= trialId,
                IsEnable=x.IsEnable,
            }).ToList();
            await _clinicalDataTrialSetRepository.AddRangeAsync(dataSets);
            var result=  await _clinicalDataTrialSetRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }

        /// <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);
        }
    }
}