namespace DocuMed.Core.EntityServices;

public class MedicalHistoryService : IMedicalHistoryService
{
    private readonly IRepositoryWrapper _repositoryWrapper;
    private readonly ICurrentUserService _currentUserService;
    private readonly IMedicalHistoryRepository _medicalHistoryRepository;

    public MedicalHistoryService(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService, IMedicalHistoryRepository medicalHistoryRepository)
    {
        _repositoryWrapper = repositoryWrapper;
        _currentUserService = currentUserService;
        _medicalHistoryRepository = medicalHistoryRepository;
    }

    public async Task<bool> EditAsync(MedicalHistoryLDto template, CancellationToken cancellationToken)
    {
        if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
            throw new AppException("دسترسی غیرمجاز", ApiResultStatusCode.UnAuthorized);
        if (template.Id == Guid.Empty)
            throw new AppException("شرح حال پیدا نشد", ApiResultStatusCode.NotFound);

        var ent = MedicalHistory.Create(template.ChiefComplaint, template.SectionId, template.FirstName,
            template.LastName, template.FatherName, template.NationalId, template.Age, template.BirthDate,
            template.PresentIllnessDetail, template.PastDiseasesHistoryDetail, template.PastSurgeryHistoryDetail,
            template.FamilyHistoryDetail, template.AllergyDetail, template.DrugHistoryDetail,
            template.AddictionHistoryDetail, template.SystemReviewDetail, template.VitalSignDetail, template.GeneralAppearanceDetail,
            template.SystolicBloodPressure, template.DiastolicBloodPressure, template.PulseRate, template.SPO2,
            template.Temperature, template.ApplicationUserId, template.MedicalHistoryTemplateId);
        ent.Id = template.Id;


        foreach (var answer in template.Answers.Where(a=>a.Id == Guid.Empty))
            ent.AddAnswer(answer.Answer, answer.Question, answer.Part, answer.QuestionType);


        foreach (var answer in template.Answers.Where(a => a.Id != Guid.Empty))
        {
            var dbAnswer = await _repositoryWrapper.SetRepository<MedicalHistoryAnswer>().TableNoTracking
                .FirstOrDefaultAsync(a => a.Id == answer.Id, cancellationToken);
            if (dbAnswer != null && dbAnswer.Answer != answer.Answer)
            {
                dbAnswer = MedicalHistoryAnswer.Create(answer.Answer, answer.Question, answer.Part, answer.QuestionType,
                    dbAnswer.MedicalHistoryId);
                dbAnswer.Id = answer.Id;
                _repositoryWrapper.SetRepository<MedicalHistoryAnswer>().Update(dbAnswer);
                await _repositoryWrapper.SaveChangesAsync(cancellationToken);
            }
        }

        _medicalHistoryRepository.Update(ent);
        await _repositoryWrapper.SaveChangesAsync(cancellationToken);

        return true;
    }

    public async Task<bool> AddAsync(MedicalHistoryLDto template, CancellationToken cancellationToken)
    {
        if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
            throw new AppException("دسترسی غیرمجاز", ApiResultStatusCode.UnAuthorized);
        var ent = MedicalHistory.Create(template.ChiefComplaint, template.SectionId, template.FirstName,
            template.LastName, template.FatherName, template.NationalId, template.Age, template.BirthDate,
            template.PresentIllnessDetail, template.PastDiseasesHistoryDetail, template.PastSurgeryHistoryDetail,
            template.FamilyHistoryDetail, template.AllergyDetail, template.DrugHistoryDetail,
            template.AddictionHistoryDetail, template.SystemReviewDetail, template.VitalSignDetail, template.GeneralAppearanceDetail,
            template.SystolicBloodPressure, template.DiastolicBloodPressure, template.PulseRate, template.SPO2,
            template.Temperature, userId,template.MedicalHistoryTemplateId);

        foreach (var answer in template.Answers)
            ent.AddAnswer(answer.Answer, answer.Question, answer.Part, answer.QuestionType);

        _medicalHistoryRepository.Add(ent);
        await _repositoryWrapper.SaveChangesAsync(cancellationToken);
        return true;
    }
}