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

namespace IRaCIS.Core.Application.Service
{
    [ApiExplorerSettings(GroupName = "Reviewer")]
    public class TrialExperienceService(IRepository<TrialExperience> _trialExperienceRepository,
        IRepository<Doctor> _doctorRepository,
           IRepository<DoctorSummarize> _doctorSummarizeRepository,
        IRepository<TrialExperienceCriteria> _trialExperienceCriteriaRepository,
        IRepository<Attachment> _attachmentRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialExperienceService
    {



        /// <summary>
        /// 根据医生Id,获取临床试验经历 界面所有数据    获取其他相关经历
        /// </summary>
        [HttpPost]
        public async Task<TrialExperienceModel> GetTrialExperience(TrialExperienceModelIndto indto)
        {
            var trialExperience = new TrialExperienceModel();

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

            trialExperience.ClinicalTrialExperienceList = await GetTrialExperienceList(new GetTrialExperienceListInDto()
            {
                DoctorId = indto.DoctorId,
                TrialId = indto.TrialId,
            });

            if (doctor != null)
            {
                var trialDoctor = new Doctor();
                if (indto.TrialId != null)
                {
                     trialDoctor = await GetTrialDoctorInfo(new GetTrialDoctorInfoInDto()
                    {
                        DoctorId = indto.DoctorId,
                        TrialId = indto.TrialId.Value,
                    });
                }
               
                trialExperience.GCP = doctor.GCP;
                trialExperience.Id = doctor.Id;
                trialExperience.GCPTime = doctor.GCPTime;
                trialExperience.GCPAgencies = doctor.GCPAgencies;
                trialExperience.OtherClinicalExperience =(indto.TrialId != null? trialDoctor.OtherClinicalExperience: doctor.OtherClinicalExperience) ?? "";
                trialExperience.OtherClinicalExperienceCN = (indto.TrialId != null ? trialDoctor.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;
        }

        /// <summary>
        /// 获取项目编辑的医生信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        public async Task<Doctor> GetTrialDoctorInfo(GetTrialDoctorInfoInDto inDto)
        {
            var doctorInfo = await _doctorRepository.Where(x => x.DoctorId == inDto.DoctorId && x.TrialId == inDto.TrialId).FirstOrDefaultAsync();
            if (doctorInfo == null)
            {

                var systemInfoDcotor = await _doctorRepository.Where(x => x.Id == inDto.DoctorId).FirstNotNullAsync();

                Doctor doctor = new Doctor()
                {
                    DoctorId = inDto.DoctorId,
                    TrialId = inDto.TrialId,
                    OtherClinicalExperience = systemInfoDcotor.OtherClinicalExperience,
                    OtherClinicalExperienceCN = systemInfoDcotor.OtherClinicalExperienceCN,
                };

                #region 概述
                ///没有就加
                var summarizeCount = await _doctorSummarizeRepository.Where(x => x.DoctorId == inDto.DoctorId && x.TrialId == inDto.TrialId).CountAsync();
                if (summarizeCount == 0)
                {
                    var main = await _doctorSummarizeRepository.Where(x => x.DoctorId == inDto.DoctorId && x.IsMain && x.TrialId == null).ProjectTo<SummarizeInfoDto>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
                    if (main != null)
                    {
                        main.Id = null;
                        main.TrialId = inDto.TrialId;
                        main.IsMain = false;
                        var entity = await _doctorSummarizeRepository.InsertOrUpdateAsync(main, true);
                    }

                }
                doctorInfo = await _doctorRepository.AddAsync(doctor, true);
                #endregion






                #region 临床试验

                var trialExperienceList = await _trialExperienceRepository.Where(o => o.DoctorId == inDto.DoctorId)
                   .Where(x=>x.TrialId==null||x.TrialId!=inDto.TrialId)
                  .Where(x => x.ExperienceDataType == ExperienceDataType.System || x.ExperienceDataType == ExperienceDataType.SystemAuto).Include(x => x.ExperienceCriteriaList).ToListAsync();
                List<TrialExperienceCriteria> criteriaList = new List<TrialExperienceCriteria>();
                foreach (var item in trialExperienceList)
                {
                    item.Trial = null;
                    item.TrialId = inDto.TrialId;
                    item.ExperienceDataType = ExperienceDataType.Trial;
                    item.Id = NewId.NextGuid();
                    item.ExperienceCriteriaList.ForEach(x => {

                        criteriaList.Add(new TrialExperienceCriteria()
                        {
                            DoctorId = item.DoctorId,
                            EvaluationCriteriaId = x.EvaluationCriteriaId,
                            TrialExperienceId = item.Id
                        });
                    });
                    item.ExperienceCriteriaList = new List<TrialExperienceCriteria>();
                }
                await _trialExperienceCriteriaRepository.AddRangeAsync(criteriaList);
                await _trialExperienceRepository.AddRangeAsync(trialExperienceList);
                await _trialExperienceRepository.SaveChangesAsync();
                #endregion

            }

            return doctorInfo;
        }

        private async Task<List<TrialExperienceListDTO>> GetTrialExperienceList(GetTrialExperienceListInDto inDto)
        {
            if (inDto.TrialId == null)
            {
                var doctorClinicalTrialExperienceList = await _trialExperienceRepository
                    .Where(o => o.DoctorId == inDto.DoctorId)
                    .Where(x => x.ExperienceDataType == ExperienceDataType.System || x.ExperienceDataType == ExperienceDataType.SystemAuto)
                    .OrderBy(t => t.CreateTime)
                    .ProjectTo<TrialExperienceListDTO>(_mapper.ConfigurationProvider).ToListAsync();
                    return doctorClinicalTrialExperienceList;
            }
            else
            {
                // 先添加
                await GetTrialDoctorInfo(new GetTrialDoctorInfoInDto()
                {
                    DoctorId = inDto.DoctorId,
                    TrialId = inDto.TrialId.Value,
                });
                var doctorClinicalTrialExperienceList = await _trialExperienceRepository
                 .Where(o => o.DoctorId == inDto.DoctorId)
                 .Where(x => x.ExperienceDataType == ExperienceDataType.Trial|| x.ExperienceDataType == ExperienceDataType.TrialAuto)
                 .Where(x => x.TrialId == inDto.TrialId.Value)
                 .OrderBy(t => t.CreateTime)
                 .ProjectTo<TrialExperienceListDTO>(_mapper.ConfigurationProvider).ToListAsync();


                return doctorClinicalTrialExperienceList;
            }
         

        }
        /// <summary> 添加或更新医生临床经验列表项</summary>

        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateTrialExperience(TrialExperienceCommand trialExperienceViewModel)
        {

            if (trialExperienceViewModel.TrialId == null)
            {
                trialExperienceViewModel.ExperienceDataType = ExperienceDataType.System;
            }
            else
            {
                trialExperienceViewModel.ExperienceDataType = ExperienceDataType.Trial;
            }

            if (trialExperienceViewModel.Id == Guid.Empty || trialExperienceViewModel.Id == null)
            {
                var trialExperience =
                _mapper.Map<TrialExperience>(trialExperienceViewModel);

                trialExperience = await _trialExperienceRepository.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 _trialExperienceCriteriaRepository.AddRangeAsync(criteriaList);


                var success = await _trialExperienceCriteriaRepository.SaveChangesAsync();
                return ResponseOutput.Result(success, trialExperience.Id);
            }
            else
            {
                var needUpdate = trialExperienceViewModel;


                await _trialExperienceRepository.UpdateFromDTOAsync(trialExperienceViewModel);

                await _trialExperienceCriteriaRepository.BatchDeleteNoTrackingAsync(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.Value
                }));

                await _trialExperienceCriteriaRepository.AddRangeAsync(criteriaList);


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

        /// <summary>
        /// 删除临床经验
        /// </summary>

        [HttpDelete, Route("{doctorId:guid}")]
        public async Task<IResponseOutput> DeleteTrialExperience(Guid doctorId)
        {
            var success = await _trialExperienceRepository.BatchDeleteNoTrackingAsync(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 _doctorRepository.BatchUpdateNoTrackingAsync(o => o.Id == updateGCPExperienceParam.Id, u => new Doctor()
            {
                GCP = updateGCPExperienceParam.GCP,
                GCPAgencies= updateGCPExperienceParam.GCPAgencies,
                GCPTime= updateGCPExperienceParam.GCPTime,
                GCPId = (updateGCPExperienceParam.GCP == 0 || updateGCPExperienceParam.GCPId == null) ? Guid.Empty : updateGCPExperienceParam.GCPId!.Value
            });

            if (updateGCPExperienceParam.GCP == 0)
            {
                await _attachmentRepository.BatchDeleteNoTrackingAsync(a => a.DoctorId == updateGCPExperienceParam.Id && a.Type == "GCP");
            }

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

        }

        /// <summary>
        /// 更新其他技能经验
        /// </summary>

        [HttpPost]
        public async Task<IResponseOutput> UpdateOtherExperience(ClinicalExperienceCommand inDto)
        {

            if (inDto.TrialId != null)
            {
                var success = await _doctorRepository.BatchUpdateNoTrackingAsync(o => o.DoctorId == inDto.DoctorId&&o.TrialId==inDto.TrialId.Value, u => new Doctor()
                {
                    OtherClinicalExperience = inDto.OtherClinicalExperience ?? string.Empty,
                    OtherClinicalExperienceCN = inDto.OtherClinicalExperienceCN ?? string.Empty
                });

                return ResponseOutput.Result(success);
            }
            else
            {
                var success = await _doctorRepository.BatchUpdateNoTrackingAsync(o => o.Id == inDto.DoctorId, u => new Doctor()
                {
                    OtherClinicalExperience = inDto.OtherClinicalExperience ?? string.Empty,
                    OtherClinicalExperienceCN = inDto.OtherClinicalExperienceCN ?? string.Empty
                });

                return ResponseOutput.Result(success);
            }
          
        }

    }
}