using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using Microsoft.AspNetCore.Mvc;

namespace IRaCIS.Application.Services
{
    [ApiExplorerSettings(GroupName = "Reviewer")]
    public class TrialExperienceService : BaseService, ITrialExperienceService
    {
        private readonly IRepository<TrialExperience> _trialExperienceRepository;
        private readonly IRepository<Doctor> _doctorRepository;
        private readonly IRepository<Attachment> _attachmentRepository;
        private readonly IRepository<TrialExperienceCriteria> _trialExperienceCriteriaRepository;



        public TrialExperienceService(IRepository<TrialExperience> trialExperienceRepository, IRepository<Doctor> doctorRepository, IRepository<Attachment> attachmentRepository,
            IRepository<TrialExperienceCriteria> trialExperienceCriteriaRepository)
        {
            _trialExperienceRepository = trialExperienceRepository;
            _doctorRepository = doctorRepository;
            _attachmentRepository = attachmentRepository;
            _trialExperienceCriteriaRepository = trialExperienceCriteriaRepository;

        }


        /// <summary>
        /// 根据医生Id，获取临床试验经历 界面所有数据
        /// </summary>
        [HttpGet("{doctorId:guid}")]
        public async Task<TrialExperienceModel> GetTrialExperience(Guid doctorId)
        {
            var trialExperience = new TrialExperienceModel();

            var doctor = await _doctorRepository.Where(o => o.Id == doctorId)
                .ProjectTo<TrialExperienceModel>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();

            trialExperience.ClinicalTrialExperienceList = await GetTrialExperienceList(doctorId);

            if (doctor != null)
            {
                trialExperience.GCP = doctor.GCP;
                trialExperience.Id = doctor.Id;
                trialExperience.OtherClinicalExperience = doctor.OtherClinicalExperience ?? "";
                trialExperience.OtherClinicalExperienceCN = doctor.OtherClinicalExperienceCN ?? "";
                var attachment = await _attachmentRepository.FirstOrDefaultAsync(t => t.Id == doctor.GCPId);
                if (attachment != null)
                {
                    trialExperience.ExpiryDateStr = attachment.ExpiryDate == null ? "" : attachment.ExpiryDate.Value.ToString("yyyy-MM-dd HH:mm");

                    trialExperience.Path = attachment.Path;
                    trialExperience.GCPFullPath =  attachment.Path + "?access_token=" + _userInfo.UserToken;
                    trialExperience.Type = attachment.Type;
                    trialExperience.FileName = attachment.FileName;
                    trialExperience.GCPId = attachment.Id;
                }
            }

            return trialExperience;
        }

        private async Task<List<TrialExperienceListDTO>> GetTrialExperienceList(Guid doctorId)
        {
            var doctorClinicalTrialExperienceList = await _trialExperienceRepository.Where(o => o.DoctorId == doctorId).OrderBy(t => t.CreateTime)
                .ProjectTo<TrialExperienceListDTO>(_mapper.ConfigurationProvider).ToListAsync();

            return doctorClinicalTrialExperienceList;
     
        }
        /// <summary> 添加或更新医生临床经验列表项</summary>
       
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand trialExperienceViewModel)
        {
            if (trialExperienceViewModel.Id == Guid.Empty || trialExperienceViewModel.Id == null)
            {
                var trialExperience =
                _mapper.Map<TrialExperience>(trialExperienceViewModel);

                trialExperience = await _repository.AddAsync(trialExperience);

                List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
                trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
                {
                    DoctorId = trialExperienceViewModel.DoctorId,
                    //EvaluationCriteria = t.EvaluationCriteria,
                    EvaluationCriteriaId = t,
                    TrialExperienceId = trialExperience.Id
                }));

                await _repository.AddRangeAsync(criteriaList);


                var success = await _repository.SaveChangesAsync();
                return ResponseOutput.Result(success, trialExperience.Id);
            }
            else
            {
                var needUpdate = await _trialExperienceRepository.FirstOrDefaultAsync(t => t.Id == trialExperienceViewModel.Id);

                if (needUpdate == null) return Null404NotFound(needUpdate);

                _mapper.Map(trialExperienceViewModel, needUpdate);
                await _repository.UpdateAsync(needUpdate);

                await _repository.BatchDeleteAsync<TrialExperienceCriteria>(t => t.TrialExperienceId == needUpdate.Id);

                List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();

                trialExperienceViewModel.EvaluationCriteriaIdList.ForEach(t => criteriaList.Add(new TrialExperienceCriteria()
                {
                    DoctorId = trialExperienceViewModel.DoctorId,
                    EvaluationCriteriaId = t,
                    TrialExperienceId = needUpdate.Id
                }));

                await _repository.AddRangeAsync<TrialExperienceCriteria>(criteriaList);


                var success = await _repository.SaveChangesAsync();
                return ResponseOutput.Result(success, trialExperienceViewModel.Id);
            }
        }

        /// <summary>
        /// 删除临床经验
        /// </summary>
       
        [HttpDelete, Route("{doctorId:guid}")]
        public async Task<IResponseOutput> DeleteTrialExperience(Guid doctorId)
        {
            var success = await _repository.BatchDeleteAsync<TrialExperience>(o => o.Id == doctorId);
            return ResponseOutput.Result(success);
        }
        /// <summary>
        /// 更新-GCP和其他临床经验
        /// </summary>
        /// <param name="updateGCPExperienceParam"></param>
        /// <returns></returns>
       
        [HttpPost]
        public async Task<IResponseOutput> UpdateGcpExperience(GCPExperienceCommand updateGCPExperienceParam)
        {
            //_attachmentRepository.Delete(t => t.DoctorId == updateGCPExperienceParam.Id && t.Type == StaticData.GCP);

            var successs = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor()
            {
                GCP = updateGCPExperienceParam.GCP,
                GCPId = updateGCPExperienceParam.GCP==0&&updateGCPExperienceParam.GCPId==null?Guid.Empty: updateGCPExperienceParam.GCPId!.Value
            });

            if (updateGCPExperienceParam.GCP == 0 && updateGCPExperienceParam.GCPId != null) 
            {
                await _repository.BatchDeleteAsync<Attachment>(a => a.Id == updateGCPExperienceParam.GCPId);
            }



            return ResponseOutput.Result(successs, updateGCPExperienceParam.GCPId.ToString());

        }

        /// <summary>
        /// 更新其他技能经验
        /// </summary>
       
        [HttpPost]
        public async Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand updateOtherClinicalExperience)
        {
            var success = await _repository.BatchUpdateAsync<Doctor>(o => o.Id == updateOtherClinicalExperience.DoctorId, u => new Doctor()
            {
                OtherClinicalExperience = updateOtherClinicalExperience.OtherClinicalExperience ?? string.Empty,
                OtherClinicalExperienceCN = updateOtherClinicalExperience.OtherClinicalExperienceCN ?? string.Empty
            });

            return ResponseOutput.Result(success);
        }

    }
}