namespace Hims.Infrastructure.Services
{
    using System;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Configurations;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Shared.EntityModels;
    using Shared.Library;
    using Shared.Library.Enums;
    using Shared.UserModels;
    using Hims.Shared.Library.Helpers;
    using Hims.Shared.UserModels.OBEncounter;
    using Hims.Shared.UserModels.Labs;
    using System.Collections.Generic;
    using System.Linq;
    using System.Collections;
    using Newtonsoft.Json;
    using Hims.Domain.Helpers;
    using Hims.Shared.UserModels.PatientMedication;
    using Hims.Shared.UserModels.Slots;

    /// <inheritdoc />
    public class OBEncounterServices : IOBEncounterService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <summary>
        /// The amazon s3 configuration.
        /// </summary>
        private readonly IAmazonS3Configuration amazonS3Configuration;

        /// <summary>
        /// The timeline service.
        /// </summary>
        private readonly ITimelineService timelineService;

        /// <summary>
        /// the aes helper
        /// </summary>
        private readonly IAESHelper aesHelper;

        /// <summary>
        /// The patient medication service
        /// </summary>
        private readonly IPatientEncounterService patientEncounterService;

        /// <inheritdoc cref="IGynEncounterService"/>
        public OBEncounterServices(ITimelineService timelineService, IUnitOfWork unitOfWork, IAmazonS3Configuration amazonS3Configuration, IAESHelper aesHelper,IPatientEncounterService patientEncounterService)
        {
            this.unitOfWork = unitOfWork;
            this.amazonS3Configuration = amazonS3Configuration;
            this.timelineService = timelineService;
            this.aesHelper = aesHelper;
            this.patientEncounterService = patientEncounterService;
        }

        public async Task<CommonResponse> AddAsync(InsertModel model)
        {
            try
            {
                var commonResponse = new CommonResponse { Status = 1 };
                var checkIf = model.IsAdmission
                    ? await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""OBEncounterId"") FROM ""ObEncounter"" WHERE ""AdmissionId"" = {model.AppointmentId}")
                    : await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""OBEncounterId"") FROM ""ObEncounter"" WHERE ""AppointmentId"" = {model.AppointmentId}");
                if (checkIf > 0)
                {
                    commonResponse.Response = -1;
                    return commonResponse;
                }
                var admission = new Admission();
                var appointment = new Appointment();
                if (model.IsAdmission)
                {
                    admission = this.unitOfWork.Admission.Find(s => s.AdmissionId == model.AppointmentId);
                }
                else
                {
                    appointment = this.unitOfWork.Appointments.Find(s => s.AppointmentId == model.AppointmentId);
                }

                var encounter = new ObEncounter
                {
                    Active = true,
                    AppointmentId = model.IsAdmission ? null : (int?)model.AppointmentId,
                    AdmissionId = model.IsAdmission ? (int?)model.AppointmentId : null,
                    OBEncounterDate = DateTime.Now,
                    CreatedBy = model.ModifiedBy,
                    CreatedDate = DateTime.Now,
                    PatientId = model.IsAdmission ? admission.PatientId : appointment.PatientId
                };

                switch (model.Type)
                {
                    case OBEncounterType.ProblemList:
                        encounter.ProblemList = model.JsonString;
                        break;
                    case OBEncounterType.Vitals:
                        encounter.Vitals = model.JsonString;
                        break;
                    case OBEncounterType.BriefRos:
                        encounter.BriefRos = model.JsonString;
                        break;
                    case OBEncounterType.ANCCaredClosure:
                        encounter.ANCCaredClosure = model.JsonString;
                        break;
                    case OBEncounterType.BreastExamination:
                        encounter.BreastExamination = model.JsonString;
                        break;
                    case OBEncounterType.ANCCardGeneration:
                        encounter.ANCCardGeneration = model.JsonString;
                        break;
                    case OBEncounterType.Complaints:
                        encounter.Complaints = model.JsonString;
                        break;
                    case OBEncounterType.ObstetricExamination:
                        encounter.ObstetricExamination = model.JsonString;
                        break;
                    case OBEncounterType.VaginalExamination:
                        encounter.VaginalExamination = model.JsonString;
                        break;
                    case OBEncounterType.OrderPrescription:
                        encounter.OrderPrescription = model.JsonString;
                        break;
                    case OBEncounterType.DrugHistory:
                        encounter.DrugHistory = model.JsonString;
                        break;
                    case OBEncounterType.MenstrualHistory:
                        encounter.MenstrualHistory = model.JsonString;
                        break;
                    case OBEncounterType.OtherDetail:
                        encounter.OtherDetail = model.JsonString;
                        break;
                    case OBEncounterType.VTERisk:
                        encounter.VTERisk = model.JsonString;
                        break;
                    case OBEncounterType.BirthHistory:
                        encounter.BirthHistory = model.JsonString;
                        break;
                    case OBEncounterType.ProcedureForm:
                        encounter.ProcedureForm = model.JsonString;
                        break;
                    case OBEncounterType.SGAScanning:
                        encounter.SGAScanning = model.JsonString;
                        break;
                    case OBEncounterType.Surgeries:
                        encounter.Surgeries = model.JsonString;
                        break;
                    case OBEncounterType.AntinantalRisk:
                        encounter.AntinantalRisk = model.JsonString;
                        break;
                    case OBEncounterType.Vaccine:
                        encounter.Vaccine = model.JsonString;
                        break;
                    case OBEncounterType.PostnantalVisit:
                        encounter.PostnantalVisit = model.JsonString;
                        break;
                    case OBEncounterType.Measure:
                        encounter.Measure = model.JsonString;
                        break;
                    case OBEncounterType.GeneralExamination:
                        encounter.GeneralExamination = model.JsonString;
                        break;
                    case OBEncounterType.Breech:
                        encounter.Breech = model.JsonString;
                        break;
                    case OBEncounterType.AncCard:
                        encounter.AncCard = model.JsonString;
                        break;
                    case OBEncounterType.Covid:
                        encounter.Covid = model.JsonString;
                        break;
                    case OBEncounterType.AnaesthesiaRecord:
                        encounter.AnaesthesiaRecord = model.JsonString;
                        break;
                    case OBEncounterType.PrePregnancyCounseling:
                        encounter.PrepregnancyCounseling = model.JsonString;
                        break;
                    case OBEncounterType.Allergies:
                        encounter.Allergies = model.JsonString;
                        break;
                    case OBEncounterType.FamilyHistory:
                        encounter.FamilyHistory = model.JsonString;
                        break;
                    case OBEncounterType.OutPatientManagement:
                        encounter.OutPatientManagement = model.JsonString;
                        break;
                    case OBEncounterType.PrePregnancyPlan:
                        encounter.PrePregnancyPlan = model.JsonString;
                        break;
                    case OBEncounterType.SpecialFeature:
                        encounter.SpecialFeature = model.JsonString;
                        break;
                    case OBEncounterType.ReferralForm:
                        encounter.ReferralForm = model.JsonString;
                        break;
                    case OBEncounterType.AdmissionSlip:
                        encounter.AdmissionSlip = model.JsonString;
                        break;
                    case OBEncounterType.MotherWithEpilepsy:
                        encounter.MotherWithEpilepsy = model.JsonString;
                        break;
                    case OBEncounterType.ExternalCephalicVersion:
                        encounter.MotherWithEpilepsy = model.JsonString;
                        break;
                    case OBEncounterType.DischargeSummary:
                        encounter.MotherWithEpilepsy = model.JsonString;
                        break;
                    case OBEncounterType.Syndromes:
                        encounter.Syndromes = model.JsonString;
                        break;
                    case OBEncounterType.NurseAssessment:
                        encounter.NurseAssessment = model.JsonString;
                        break;
                    case OBEncounterType.OutSideTests:
                        encounter.OutSideTests = model.JsonString;
                        break;
                    case OBEncounterType.NeonatalAssessmentForm:
                        encounter.NeonatalAssessmentForm = model.JsonString;
                        break;
                    case OBEncounterType.ScanAppointmentDetails:
                        encounter.ScanAppointmentDetails = model.JsonString;
                        break;
                    case OBEncounterType.InductionForm:
                        encounter.InductionForm = model.JsonString;
                        break;
                    case OBEncounterType.NormalDeliveryForm:
                        encounter.NormalDeliveryForm = model.JsonString;
                        break;
                    case OBEncounterType.LSCS:
                        encounter.LSCS = model.JsonString;
                        break;
                    case OBEncounterType.AdmissionDetails:
                        encounter.AdmissionDetails = model.JsonString;
                        break;
                    case OBEncounterType.IUFD:
                        encounter.IUFD = model.JsonString;
                        break;
                    case OBEncounterType.DoctorsReview:
                        encounter.DoctorsReview = model.JsonString;
                        break;
                    case OBEncounterType.Reminder:
                        encounter.Reminder = model.JsonString;
                        break;
                    case OBEncounterType.RiskCategoryAtAdm:
                        encounter.RiskCategoryAtAdm = model.JsonString;
                        break;
                }
                if(model.Type== OBEncounterType.AncCard)
                {
                    encounter.SpecialFeature = model.JsonString;
                }
                if(model.Type == OBEncounterType.Measure)
                {
                    encounter.MeasureCommonData = model.JsonString;
                }
                if (model.Type == OBEncounterType.AncCardCloseCommonData)
                {
                    encounter.AncCardCloseCommonData = model.JsonString;
                }
                if (model.RefferalOrder != null)
                {
                    encounter.RefferalOrder = model.JsonString;
                }
                if (model.Type == OBEncounterType.ReferralForm)
                {
                    var value = JsonConvert.DeserializeObject<ReferralFormModel>(model.JsonString);
                    value.AppointmentId = model.AppointmentId;
                    await this.InsertReferralForm(value);
                }
                var response = await this.unitOfWork.ObEncounters.InsertAsync(encounter);
                commonResponse.Response = response;
                var msg = " Added OB Encounter ";
                await this.timelineService.LogAsync(new TimelineModel
                {
                    PatientId = model.IsAdmission ? admission.PatientId : appointment.PatientId,
                    TimelineActionId = TimelineAction.EncounterAdded,
                    CreatedBy = model.ModifiedBy,
                    Description = msg,
                    AppointmentId = !model.IsAdmission ? appointment.AppointmentId : 0
                }) ;
                return commonResponse;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public async Task<CommonResponse> UpdateAsync(InsertModel model)
        {
            var commonResponse = new CommonResponse { Status = 1 };
            var encounter = await this.unitOfWork.ObEncounters.FindAsync(m => m.OBEncounterId == model.OBEncounterId);

            var checkIf = model.IsAdmission
                    ? await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""OBEncounterId"") FROM ""ObEncounter"" WHERE ""AdmissionId"" = '{model.AppointmentId}' AND ""OBEncounterId"" <> '{model.OBEncounterId}'")
                    : await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""OBEncounterId"") FROM ""ObEncounter"" WHERE ""AppointmentId"" = '{model.AppointmentId}' AND ""OBEncounterId"" <> '{model.OBEncounterId}'");

            if (checkIf > 0)
            {
                commonResponse.Response = -1;
                return commonResponse;
            }
            var admission = new Admission();
            var appointment = new Appointment();
            if (model.IsAdmission)
            {
                admission = this.unitOfWork.Admission.Find(s => s.AdmissionId == model.AppointmentId);
            }
            else
            {
                appointment = this.unitOfWork.Appointments.Find(s => s.AppointmentId == model.AppointmentId);
            }
            encounter.ModifiedBy = model.ModifiedBy;
            encounter.ModifiedDate = DateTime.Now;

            switch (model.Type)
            {
                case OBEncounterType.Vitals:
                    encounter.Vitals = model.JsonString;
                    break;
                case OBEncounterType.ProblemList:
                    encounter.ProblemList = model.JsonString;
                    break;
                case OBEncounterType.BriefRos:
                    encounter.BriefRos = model.JsonString;
                    break;
                case OBEncounterType.GeneticScreening:
                    encounter.GeneticScreening = model.JsonString;
                    break;
                case OBEncounterType.InfectionHistory:
                    encounter.InfectionHistory = model.JsonString;
                    break;
                case OBEncounterType.ANCCaredClosure:
                    encounter.ANCCaredClosure = model.JsonString;
                    break;
                case OBEncounterType.BreastExamination:
                    encounter.BreastExamination = model.JsonString;
                    break;
                case OBEncounterType.ANCCardGeneration:
                    encounter.ANCCardGeneration = model.JsonString;
                    break;
                case OBEncounterType.Complaints:
                    encounter.Complaints = model.JsonString;
                    break;
                case OBEncounterType.ObstetricExamination:
                    encounter.ObstetricExamination = model.JsonString;
                    break;
                case OBEncounterType.VaginalExamination:
                    encounter.VaginalExamination = model.JsonString;
                    break;
                case OBEncounterType.PlanOfManagement:
                    encounter.PlanOfManagement = model.JsonString;
                    break;
                case OBEncounterType.OrderPrescription:
                    encounter.OrderPrescription = model.JsonString;
                    break;
                case OBEncounterType.DrugHistory:
                    encounter.DrugHistory = model.JsonString;
                    break;
                case OBEncounterType.MenstrualHistory:
                    encounter.MenstrualHistory = model.JsonString;
                    break;
                case OBEncounterType.OtherDetail:
                    encounter.OtherDetail = model.JsonString;
                    break;

                case OBEncounterType.VTERisk:
                    encounter.VTERisk = model.JsonString;
                    break;

                case OBEncounterType.BirthHistory:
                    encounter.BirthHistory = model.JsonString;
                    break;

                case OBEncounterType.ProcedureForm:
                    encounter.ProcedureForm = model.JsonString;
                    break;
                case OBEncounterType.SGAScanning:
                    encounter.SGAScanning = model.JsonString;
                    break;

                case OBEncounterType.Surgeries:
                    encounter.Surgeries = model.JsonString;
                    break;

                case OBEncounterType.AntinantalRisk:
                    encounter.AntinantalRisk = model.JsonString;
                    break;
                case OBEncounterType.Vaccine:
                    encounter.Vaccine = model.JsonString;
                    break;
                case OBEncounterType.PostnantalVisit:
                    encounter.PostnantalVisit = model.JsonString;
                    break;
                case OBEncounterType.Measure:
                    encounter.Measure = model.JsonString;
                    break;
                case OBEncounterType.GeneralExamination:
                    encounter.GeneralExamination = model.JsonString;
                    break;
                case OBEncounterType.Breech:
                    encounter.Breech = model.JsonString;
                    break;
                case OBEncounterType.AncCard:
                    encounter.AncCard = model.JsonString;
                    break;
                case OBEncounterType.Covid:
                    encounter.Covid = model.JsonString;
                    break;
                case OBEncounterType.AnaesthesiaRecord:
                    encounter.AnaesthesiaRecord = model.JsonString;
                    break;
                case OBEncounterType.PrePregnancyCounseling:
                    encounter.PrepregnancyCounseling = model.JsonString;
                    break;
                case OBEncounterType.Allergies:
                    encounter.Allergies = model.JsonString;
                    break;
                case OBEncounterType.FamilyHistory:
                    encounter.FamilyHistory = model.JsonString;
                    break;
                case OBEncounterType.OutPatientManagement:
                    encounter.OutPatientManagement = model.JsonString;
                    break;
                case OBEncounterType.PrePregnancyPlan:
                    encounter.PrePregnancyPlan = model.JsonString;
                    break;
                case OBEncounterType.SpecialFeature:
                    encounter.SpecialFeature = model.JsonString;
                    break;
                case OBEncounterType.ReferralForm:
                    encounter.ReferralForm = model.JsonString;
                    break;
                case OBEncounterType.AdmissionSlip:
                    encounter.AdmissionSlip = model.JsonString;
                    break;
                case OBEncounterType.MotherWithEpilepsy:
                    encounter.MotherWithEpilepsy = model.JsonString;
                    break;
                case OBEncounterType.ExternalCephalicVersion:
                    encounter.ExternalCephalicVersion = model.JsonString;
                    break;
                case OBEncounterType.DischargeSummary:
                    encounter.DischargeSummary = model.JsonString;
                    break;
                case OBEncounterType.Syndromes:
                    encounter.Syndromes = model.JsonString;
                    break;
                case OBEncounterType.OPManagement:
                    encounter.OPManagement = model.JsonString;
                    break;
                case OBEncounterType.NurseAssessment:
                    encounter.NurseAssessment = model.JsonString;
                    break;
                case OBEncounterType.OutSideTests:
                    encounter.OutSideTests = model.JsonString;
                    break;
                case OBEncounterType.NeonatalAssessmentForm:
                    encounter.NeonatalAssessmentForm = model.JsonString;
                    break;
                case OBEncounterType.ScanAppointmentDetails:
                    encounter.ScanAppointmentDetails = model.JsonString;
                    break;
                case OBEncounterType.InductionForm:
                    encounter.InductionForm = model.JsonString;
                    break;
                case OBEncounterType.NormalDeliveryForm:
                    encounter.NormalDeliveryForm = model.JsonString;
                    break;
                case OBEncounterType.LSCS:
                    encounter.LSCS = model.JsonString;
                    break;
                case OBEncounterType.AdmissionDetails:
                    encounter.AdmissionDetails = model.JsonString;
                    break;
                case OBEncounterType.IUFD:
                    encounter.IUFD = model.JsonString;
                    break;
                case OBEncounterType.DoctorsReview:
                    encounter.DoctorsReview = model.JsonString;
                    break;
                case OBEncounterType.Reminder:
                    encounter.Reminder = model.JsonString;
                    break;
                case OBEncounterType.RiskCategoryAtAdm:
                    encounter.RiskCategoryAtAdm = model.JsonString;
                    break;
            }
            if (model.Type == OBEncounterType.AncCard)
            {
                encounter.SpecialFeature = model.JsonString;
            }
            if (model.Type == OBEncounterType.Measure)
            {
                encounter.MeasureCommonData = model.JsonString;
            }
            if (model.Type == OBEncounterType.ANCCaredClosure)
            {
                encounter.AncCardCloseCommonData = model.JsonString;
            }
            if (model.RefferalOrder != null)
            {
                encounter.RefferalOrder = model.RefferalOrder;
            }
            if (model.Type == OBEncounterType.ReferralForm)
            {

                var value = JsonConvert.DeserializeObject<ReferralFormModel>(model.JsonString);
                value.AppointmentId = model.AppointmentId;
                await this.InsertReferralForm(value);
                await this.timelineService.LogAsync(new TimelineModel
                {
                    PatientId = model.IsAdmission ? admission.PatientId : appointment.PatientId,
                    TimelineActionId = TimelineAction.CrossConsultation,
                    CreatedBy = model.ModifiedBy,
                    Description = "Added Cross Consultation",
                    AppointmentId = !model.IsAdmission ? appointment.AppointmentId : 0
                });
            }
            var updated = await this.unitOfWork.ObEncounters.UpdateAsync(encounter);

            commonResponse.Response = updated > 0 ? encounter.OBEncounterId : 0;
            return commonResponse;
        }



        public async Task<ObEncounterResource> FindDashboardAsync(int appointmentId, OBEncounterType type, bool isAdmission)
        {
            try
            {
                //    var obEncounter = isAdmission
                //                       ? await this.unitOfWork.ObEncounters.FindAsync(m => m.AdmissionId == appointmentId)
                //                       : await this.unitOfWork.ObEncounters.FindAsync(m => m.AppointmentId == appointmentId);
                var obEncounter = new ObEncounterModel();
                var admRecord = new Admission();
                var appRecord = new Appointment();
                var findAppointmentId = 0;
                if (appointmentId != 0)
                {
                    var query = "";
                    if (isAdmission)
                    {
                        admRecord = this.unitOfWork.Admission.Find(s => s.AdmissionId == appointmentId);
                        findAppointmentId = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AdmissionId"" = {appointmentId}");
                    }
                    else
                    {
                        appRecord = this.unitOfWork.Appointments.Find(s => s.AppointmentId == appointmentId);
                        findAppointmentId = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AppointmentId"" = {appointmentId}");
                    }

                    if (findAppointmentId == 0)
                    {
                        query = isAdmission ? $@"select * from ""ObEncounter"" where ""PatientId""={admRecord.PatientId} order by 1 desc " :
                            $@"select * from ""ObEncounter"" where ""PatientId""={appRecord.PatientId} order by 1 desc ";

                    }
                    else
                    {
                        query = isAdmission ? $@"select * from ""ObEncounter"" where ""PatientId""={admRecord.PatientId}  and  ""AdmissionId""={appointmentId} order by 1 desc " :
                             $@"select * from ""ObEncounter"" where ""PatientId""={appRecord.PatientId}  and  ""AppointmentId""={appointmentId} order by 1 desc ";
                    }
                    obEncounter = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(query);
                }
                var obEncounterResource = new ObEncounterResource
                {

                    AppointmentId = isAdmission ? admRecord.AdmissionId : appRecord.AppointmentId,
                    OBEncounterId = null,
                    JsonString = null
                };

                if (obEncounter != null)
                {
                    obEncounterResource.OBEncounterId = obEncounter.OBEncounterId;
                    switch (type)
                    {
                        case OBEncounterType.Vitals:
                            obEncounterResource.JsonString = obEncounter.Vitals;
                            break;
                        case OBEncounterType.ProblemList:
                            obEncounterResource.JsonString = obEncounter.ProblemList;
                            break;
                        case OBEncounterType.BriefRos:
                            obEncounterResource.JsonString = obEncounter.BriefRos;
                            break;
                        case OBEncounterType.GeneticScreening:
                            obEncounterResource.JsonString = obEncounter.GeneticScreening;
                            break;
                        case OBEncounterType.InfectionHistory:
                            obEncounterResource.JsonString = obEncounter.InfectionHistory;
                            break;
                        case OBEncounterType.ANCCaredClosure:
                            obEncounterResource.JsonString = obEncounter.ANCCaredClosure;
                            break;

                        case OBEncounterType.BreastExamination:
                            obEncounterResource.JsonString = obEncounter.BreastExamination;
                            break;

                        case OBEncounterType.VaginalExamination:
                            obEncounterResource.JsonString = obEncounter.VaginalExamination;
                            break;
                        case OBEncounterType.PlanOfManagement:
                            obEncounterResource.JsonString = obEncounter.PlanOfManagement;
                            break;

                        case OBEncounterType.ANCCardGeneration:
                            obEncounterResource.JsonString = obEncounter.ANCCardGeneration;
                            break;
                        case OBEncounterType.Complaints:
                            obEncounterResource.JsonString = obEncounter.Complaints;
                            break;
                        case OBEncounterType.ObstetricExamination:
                            obEncounterResource.JsonString = obEncounter.ObstetricExamination;
                            break;
                        case OBEncounterType.OrderPrescription:
                            obEncounterResource.JsonString = obEncounter.OrderPrescription;
                            break;
                        case OBEncounterType.DrugHistory:
                            obEncounterResource.JsonString = obEncounter.DrugHistory;
                            break;
                        case OBEncounterType.MenstrualHistory:
                            obEncounterResource.JsonString = obEncounter.MenstrualHistory;
                            break;
                        case OBEncounterType.VTERisk:
                            obEncounterResource.JsonString = obEncounter.VTERisk;
                            break;

                        case OBEncounterType.BirthHistory:
                            obEncounterResource.JsonString = obEncounter.BirthHistory;
                            break;

                        case OBEncounterType.ProcedureForm:
                            obEncounterResource.JsonString = obEncounter.ProcedureForm;
                            break;

                        case OBEncounterType.SGAScanning:
                            obEncounterResource.JsonString = obEncounter.SGAScanning;
                            break;

                        case OBEncounterType.Surgeries:
                            obEncounterResource.JsonString = obEncounter.Surgeries;
                            break;

                        case OBEncounterType.AntinantalRisk:
                            obEncounterResource.JsonString = obEncounter.AntinantalRisk;
                            break;

                        case OBEncounterType.OtherDetail:
                            obEncounterResource.JsonString = obEncounter.OtherDetail;
                            break;
                        case OBEncounterType.Vaccine:
                            obEncounterResource.JsonString = obEncounter.Vaccine;
                            break;
                        case OBEncounterType.PostnantalVisit:
                            obEncounterResource.JsonString = obEncounter.PostnantalVisit;
                            break;
                        case OBEncounterType.Measure:
                            obEncounterResource.JsonString = obEncounter.Measure;
                            break;
                        case OBEncounterType.GeneralExamination:
                            obEncounterResource.JsonString = obEncounter.GeneralExamination;
                            break;
                        case OBEncounterType.Breech:
                            obEncounterResource.JsonString = obEncounter.Breech;
                            break;
                        case OBEncounterType.AncCard:
                            obEncounterResource.JsonString = obEncounter.AncCard;
                            break;
                        case OBEncounterType.Covid:
                            obEncounterResource.JsonString = obEncounter.Covid;
                            break;
                        case OBEncounterType.AnaesthesiaRecord:
                            obEncounterResource.JsonString = obEncounter.AnaesthesiaRecord;
                            break;
                        case OBEncounterType.PrePregnancyCounseling:
                            obEncounterResource.JsonString = obEncounter.PrepregnancyCounseling;
                            break;
                        case OBEncounterType.Allergies:
                            obEncounterResource.JsonString = obEncounter.Allergies;
                            break;
                        case OBEncounterType.FamilyHistory:
                            obEncounterResource.JsonString = obEncounter.FamilyHistory;
                            break;
                        case OBEncounterType.OutPatientManagement:
                            obEncounterResource.JsonString = obEncounter.OutPatientManagement;
                            break;
                        case OBEncounterType.PrePregnancyPlan:
                            obEncounterResource.JsonString = obEncounter.PrePregnancyPlan;
                            break;
                        case OBEncounterType.SpecialFeature:
                            obEncounterResource.JsonString = obEncounter.SpecialFeature;
                            break;
                        case OBEncounterType.ReferralForm:
                            obEncounterResource.JsonString = obEncounter.ReferralForm;
                            break;
                        case OBEncounterType.RefferalOrder:
                            obEncounterResource.JsonString = obEncounter.RefferalOrder;
                            break;
                        case OBEncounterType.AdmissionSlip:
                            obEncounterResource.JsonString = obEncounter.AdmissionSlip;
                            break;
                        case OBEncounterType.MotherWithEpilepsy:
                            obEncounterResource.JsonString = obEncounter.MotherWithEpilepsy;
                            break;
                        case OBEncounterType.ExternalCephalicVersion:
                            obEncounterResource.JsonString = obEncounter.ExternalCephalicVersion;
                            break;
                        case OBEncounterType.DischargeSummary:
                            obEncounterResource.JsonString = obEncounter.DischargeSummary;
                            break;
                        case OBEncounterType.Syndromes:
                            obEncounterResource.JsonString = obEncounter.Syndromes;
                            break;
                        case OBEncounterType.OPManagement:
                            obEncounterResource.JsonString = obEncounter.OPManagement;
                            break;
                        case OBEncounterType.NurseAssessment:
                            obEncounterResource.JsonString = obEncounter.NurseAssessment;
                            break;
                        case OBEncounterType.OutSideTests:
                            obEncounterResource.JsonString = obEncounter.OutSideTests;
                            break;
                        case OBEncounterType.NeonatalAssessmentForm:
                            obEncounterResource.JsonString = obEncounter.NeonatalAssessmentForm;
                            break;
                        case OBEncounterType.ScanAppointmentDetails:
                            obEncounterResource.JsonString = obEncounter.ScanAppointmentDetails;
                            break;
                        case OBEncounterType.InductionForm:
                            obEncounterResource.JsonString = obEncounter.InductionForm;
                            break;
                        case OBEncounterType.NormalDeliveryForm:
                            obEncounterResource.JsonString = obEncounter.NormalDeliveryForm;
                            break;
                        case OBEncounterType.LSCS:
                            obEncounterResource.JsonString = obEncounter.LSCS;
                            break;
                        case OBEncounterType.AdmissionDetails:
                            obEncounterResource.JsonString = obEncounter.AdmissionDetails;
                            break;
                        case OBEncounterType.IUFD:
                            obEncounterResource.JsonString = obEncounter.IUFD;
                            break;
                        case OBEncounterType.DoctorsReview:
                            obEncounterResource.JsonString = obEncounter.DoctorsReview;
                            break;
                        case OBEncounterType.Reminder:
                            obEncounterResource.JsonString = obEncounter.Reminder;
                            break;
                        case OBEncounterType.RiskCategoryAtAdm:
                            obEncounterResource.JsonString = obEncounter.RiskCategoryAtAdm;
                            break;
                    }
                }

                return obEncounterResource;
            }
            catch (Exception ex)
            {
                throw;
            }

        }

        /// <inheritdoc />
        public async Task<ObEncounterModel> FindAsync(int appointmentId, bool isAdmission)
        {
            var result = new ObEncounterModel();
            if (appointmentId != 0)
            {
                var query = "";
                var getId = 0;
                var addRecords = new Admission();
                var appRecord = new Appointment();
                if (isAdmission)
                {
                    addRecords = this.unitOfWork.Admission.Find(s => s.AdmissionId == appointmentId);
                    getId = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AdmissionId"" = {addRecords.AdmissionId}");
                }
                else
                {
                    appRecord = this.unitOfWork.Appointments.Find(s => s.AppointmentId == appointmentId);
                    if (appRecord != null)
                    {
                        getId = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AppointmentId"" = {appRecord.AppointmentId}");
                    }
                }
                if (getId == 0)
                {
                    var AptCnt = 0;
                    if (isAdmission)
                    {
                        query = $@"select * from ""ObEncounter"" where ""PatientId""={addRecords.PatientId} order by 1 desc ";
                        AptCnt = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""PatientId"" = {addRecords.PatientId}");
                    }
                    else
                    {
                        if (appRecord != null && appRecord.PatientId != 0)
                        {
                            query = $@"select * from ""ObEncounter"" where ""PatientId""={appRecord.PatientId} order by 1 desc ";
                            AptCnt = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""PatientId"" = {appRecord.PatientId}");

                        }
                    }
                    if (AptCnt > 0)
                    {
                        await AddExistedAsync(appointmentId, isAdmission ? addRecords.PatientId : appRecord.PatientId, isAdmission);
                        query = isAdmission ? $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where ob.""PatientId""={addRecords.PatientId}  and  ob.""AdmissionId""={addRecords.AdmissionId} order by 1 desc " :
                         $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where ob.""PatientId""={appRecord.PatientId}  and  ob.""AppointmentId""={appRecord.AppointmentId} order by 1 desc ";
                        result = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(query);
                    }
                   
                }
                else
                {
                    query = isAdmission ? $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where ob.""PatientId""={addRecords.PatientId}  and  ob.""AdmissionId""={addRecords.AdmissionId} order by 1 desc " :
                    $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where ob.""PatientId""={appRecord.PatientId}  and  ob.""AppointmentId""={appRecord.AppointmentId} order by 1 desc ";
                    result = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(query);
                }
            }
            return result;

        }
        public async Task<CommonResponse> AddExistedAsync(int appointmentId, int patientId, bool isAdmission)
        {
            var count = 0;
            var commonResponse = new CommonResponse { Status = 1 };
            var records = new ObEncounterModel();
            var admissionRecords = new Admission();
            var appointmentRecords = new Appointment();
            var query = $@"select * from ""ObEncounter"" where ""PatientId""={patientId} order by 1 desc ";
            records = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(query);
            if (isAdmission)
            {
                admissionRecords = this.unitOfWork.Admission.Find(s => s.AdmissionId == appointmentId);

            }
            else
            {
                appointmentRecords = this.unitOfWork.Appointments.Find(s => s.AppointmentId == appointmentId);
            }
            var ancQuerry = $@"select * from ""ANCCardGeneration"" where ""PatientId""={patientId} and ""Active""=true order by 1 desc ";
            var ancCardRecords = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ANCCardGeneration>(query);
            var ancRecords = new ANCCardGeneration();
            var ancCardQuerry = isAdmission ? $@"select * from ""ANCCardGeneration"" where ""PatientId""={patientId}  order by 1 desc " :
                $@"select * from ""ANCCardGeneration"" where ""PatientId""={patientId}   order by 1 desc ";
            ancRecords = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ANCCardGeneration>(ancCardQuerry);

            var encounter = new ObEncounter
            {
                Active = true,
                AdmissionId =  admissionRecords.AdmissionId,
                AppointmentId =  appointmentRecords.AppointmentId,
                CreatedDate = DateTime.UtcNow,
                PatientId = isAdmission ? admissionRecords.PatientId : appointmentRecords.PatientId,
            };
            if (records != null )
            {
                if (ancRecords !=null && ancRecords.Active == false)
                {
                   
                    encounter.MeasureCommonData=records.MeasureCommonData;
                    encounter.AncCardCloseCommonData=records.AncCardCloseCommonData;
                    encounter.ANCCardGenerationId =  0;
                }
                else
                {
                    encounter.ANCCardGeneration = records.ANCCardGeneration;
                    encounter.AncCard = records.AncCard;
                    encounter.BirthHistory = records.BirthHistory;
                    encounter.ProblemList = records.ProblemList;
                    encounter.FamilyHistory = records.FamilyHistory;
                    encounter.Surgeries = records.Surgeries;
                    encounter.Allergies = records.Allergies;
                    encounter.AntinantalRisk = records.AntinantalRisk;
                    encounter.PostnantalVisit = records.PostnantalVisit;
                    encounter.AnaesthesiaRecord = records.AnaesthesiaRecord;
                    encounter.PrepregnancyCounseling = records.PrepregnancyCounseling;
                    encounter.PrePregnancyPlan = records.PrePregnancyPlan;
                    encounter.SpecialFeature = records.SpecialFeature;
                    encounter.OutPatientManagement = records.OutPatientManagement;
                    encounter.ReferralForm = records.ReferralForm;
                    encounter.ANCCardGenerationId = records.ANCCardGenerationId;
                    encounter.PatientId = records.PatientId;
                    encounter.OutSideTests = records.OutSideTests;
                    encounter.MeasureCommonData = records.MeasureCommonData;
                    encounter.AncCardCloseCommonData = records.AncCardCloseCommonData;
                    encounter.AdmissionSlip = records.AdmissionSlip;
                }
            }
            var existedRecords  = this.unitOfWork.ObEncounters.Find(s => s.AppointmentId == appointmentId);
            count++;
            if(count == 1)
            {
                var response = await this.unitOfWork.ObEncounters.InsertAsync(encounter);
                commonResponse.Response = response;
                return commonResponse;
            }

                
            
            return commonResponse;
           
        }
        /// <inheritdoc />
        public Task<ObEncounterFullTranscriptModel> FindFullTranscriptAsync(int appointmentId)
        {
            var query = $@"SELECT A.""AppointmentId"", A.""AppointmentNo"",A.""AppointmentDate"",A.""AppointmentTime"", 
                             (case when A.""PatientFamilyId"" is not null then PF.""FullName"" else P.""FullName"" end) AS ""PatientName"", 
                             (case when A.""PatientFamilyId"" is not null then PF.""Gender"" else P.""Gender"" end) AS ""PatientGender"",C.""CountryCode"" AS ""PatientCountryCode"",
                             CONCAT(Pr.""Salutation"",' ', Pr.""FullName"") AS ""ProviderName"",P.""Mobile"" AS ""PatientMobile"",
                            (case when A.""PatientFamilyId"" is not null then PF.""Age"" else P.""Age"" end) AS ""PatientAge"", P.""DateOfBirth"" AS ""PatientDateOfBirth"",
							(CASE WHEN P.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', P.""Guid"", '/', P.""ThumbnailUrl"") ELSE NULL END) AS ""PatientThumbnailUrl"",
							""OBEncounterId"",CE.""ProblemList"",""GeneticScreening"",""InfectionHistory"",""BriefRos"",
                             ""Vitals"",""BreastExamination"",""Complaints"",""ObstetricExamination"", ""OtherDetail"",
                            ""VaginalExamination"",""ANCCaredClosure"",""ANCCardGeneration"",""PlanOfManagement"",""VTERisk"",CE.""BirthHistory"",""ProcedureForm"",""SGAScanning"",CE.""Surgeries"",""OrderPrescription"", ""DrugHistory"", ""MenstrualHistory"",""AdmissionSlip"",""MotherWithEpilepsy"",""ExternalCephalicVersion"", ""NurseAssessment"",
                            ""AntinantalRisk"", ""Measure"",""GeneralExamination"", ""Breech"",""AncCard"",""Covid"",""Vaccine"", ""PostnantalVisit"",""AnaesthesiaRecord"",""PrepregnancyCounseling"",CE.""FamilyHistory"", ""OutPatientManagement"", ""PrePregnancyPlan"", ""SpecialFeature"", ""ReferralForm"", ""DischargeSummary"", ""OutSideTests"", ""RefferalOrder"",""Allergies"",""Reminder""
                            FROM ""Appointment"" A
							LEFT JOIN ""ObEncounter"" ob ON A.""AppointmentId""= ob.""AppointmentId""
                            left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
							LEFT JOIN ""AppointmentSymptom"" ATS ON  ATS.""AppointmentId"" = A.""AppointmentId""
                            LEFT JOIN ""Provider"" pr on pr.""ProviderId""=A.""ProviderId""
							JOIN ""Patient"" P ON P.""PatientId"" = A.""PatientId""
                            Left join ""PatientFamily"" PF on PF.""PatientFamilyId"" = A.""PatientFamilyId""
							LEFT JOIN ""Country"" C ON C.""CountryId""=P.""CountryId""
                            where A.""AppointmentId"" = {appointmentId} AND A.""Active"" IS TRUE";
            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterFullTranscriptModel>(query);
        }

        public Task<ObEncounterFullTranscriptModel> FindPrescriptionAsync(int appointmentId)
        {
            var query = $@"SELECT A.""AppointmentId"", A.""AppointmentNo"",A.""AppointmentDate"",A.""AppointmentTime"", 
                             (case when A.""PatientFamilyId"" is not null then PF.""FullName"" else P.""FullName"" end) AS ""PatientName"", 
                             (case when A.""PatientFamilyId"" is not null then PF.""Gender"" else P.""Gender"" end) AS ""PatientGender"",C.""CountryCode"" AS ""PatientCountryCode"",
                             CONCAT(Pr.""Salutation"",' ', Pr.""FullName"") AS ""ProviderName"",P.""Mobile"" AS ""PatientMobile"",P.""UMRNo"" as ""PatientNo"",P.""FatherOrHusband"" as ""Partner"",
                            (case when A.""PatientFamilyId"" is not null then PF.""Age"" else P.""Age"" end) AS ""PatientAge"", P.""DateOfBirth"" AS ""PatientDateOfBirth"",
							(CASE WHEN P.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', P.""Guid"", '/', P.""ThumbnailUrl"") ELSE NULL END) AS ""PatientThumbnailUrl"",
							""OBEncounterId"",""ProblemList"",""GeneticScreening"",""InfectionHistory"",""BriefRos"",
                             ""Vitals"",""BreastExamination"",""Complaints"",""ObstetricExamination"", ""OtherDetail"",
                            ""VaginalExamination"",""ANCCaredClosure"",""ANCCardGeneration"",""PlanOfManagement"",""VTERisk"",""BirthHistory"",""ProcedureForm"",""SGAScanning"",""Surgeries"",""OrderPrescription"", ""DrugHistory"", ""MenstrualHistory"",""Allergies"",""AdmissionSlip"",""MotherWithEpilepsy"",""ExternalCephalicVersion"",""NurseAssessment"",""RefferalOrder"",
                            ""AntinantalRisk"", ""Measure"",""GeneralExamination"", ""Breech"",""AncCard"",""Covid"",""Vaccine"", ""PostnantalVisit"",""AnaesthesiaRecord"",""PrepregnancyCounseling"",pr.""FriendlyName"",pr.""Email"",pr.""ProviderNo"", ""OutPatientManagement"" ""PrePregnancyPlan"", ""SpecialFeature"", ""ReferralForm"",""DischargeSummary"", ""ScanAppointmentDetails""
                            FROM ""Appointment"" A
							LEFT JOIN ""ObEncounter"" ob ON A.""AppointmentId""= ob.""AppointmentId""
							LEFT JOIN ""AppointmentSymptom"" ATS ON  ATS.""AppointmentId"" = A.""AppointmentId""
                            LEFT JOIN ""Provider"" pr on pr.""ProviderId""=A.""ProviderId""
							JOIN ""Patient"" P ON P.""PatientId"" = A.""PatientId""
                            Left join ""PatientFamily"" PF on PF.""PatientFamilyId"" = A.""PatientFamilyId""
							LEFT JOIN ""Country"" C ON C.""CountryId""=P.""CountryId""
                            where A.""AppointmentId"" = {appointmentId} AND A.""Active"" IS TRUE";

            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterFullTranscriptModel>(query);
        }

        public async Task<int> AddAncAsync(ANCCardGenerationModel model, string locationId)
        {

            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""ANCCardGeneration"" where  ""PatientId""={model.PatientId} and ""Active""= true");
            var anc = new InsertModel();
            if (model.IsAdmission)
            {
                // anc.AdmissionId = model.AppointmentId;
                var admission = new Admission();
                var adm = await this.unitOfWork.Admission.FindAsync(s => s.AdmissionId == model.AppointmentId);
                model.ProviderId = adm.ProviderId;
            }
            anc.AppointmentId = (int)model.AppointmentId;
            anc.JsonString = (string)model.JsonString;
            anc.Type = model.Type;
            anc.ModifiedBy = (int)model.ModifiedBy;
            anc.IsAdmission = model.IsAdmission;
            var obValues = new ObEncounter();
            if (model.IsAdmission)
            {
                obValues = await this.unitOfWork.ObEncounters.FindAsync(s => s.AdmissionId == model.AppointmentId);
            }
            else
            {

                obValues = await this.unitOfWork.ObEncounters.FindAsync(s => s.AppointmentId == model.AppointmentId);

            }
            if (checkIf > 0)
            {

                var record = await this.unitOfWork.ANCCardGeneration.FindAsync(p => p.PatientId == model.PatientId && p.Active == true);
                record.Department = model.Department;
                record.HusbandName = model.HusbandName;
                record.Remarks = model.Remarks;
                record.RegistrationDate = model.RegistrationDate;
                record.ProviderId = model.ProviderId;
                record.PatientId = model.PatientId;
                record.HusbandAge = model.HusbandAge;
                record.Active = true;
                record.ANCNoExists = model.ANCNoExists;
                record.ConsultantDoctor = model.ConsultantDoctor;
                return await this.unitOfWork.ANCCardGeneration.UpdateAsync(record);
            }
            else
            {
                var reason = new ANCCardGeneration
                {
                    Department = model.Department,
                    HusbandName = model.HusbandName,
                    Remarks = model.Remarks,
                    RegistrationDate = model.RegistrationDate,
                    ProviderId = model.ProviderId,
                    PatientId = model.PatientId,
                    HusbandAge = model.HusbandAge,
                    ANCNoExists = model.ANCNoExists,
                    Active = true,
                    ConsultantDoctor = model.ConsultantDoctor,
                };
                var locations = await this.unitOfWork.Locations.FindAsync(s => s.LocationId == int.Parse(locationId));
                var loc = locations.NameLoc;
                var currentYear = DateTime.Now.Year.ToString();
                var lastAncNo = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<ANCCardGenerationModel>($@"select * from ""ANCCardGeneration"" order by 1 desc limit 1");
                var number = 0;
                if (lastAncNo == null)
                {
                    number = 1;
                }
                else
                {
                    var split = lastAncNo.ANCNo.Split("/");
                    number = int.Parse(split[0]);
                }
                var newAncNumber = (number + 1) + "/" + currentYear + "/" + loc;
                reason.ANCNo = newAncNumber;
                var result = 0;
                try
                {
                    result = await this.unitOfWork.ANCCardGeneration.InsertAsync(reason);

                }
                catch (Exception e)
                {

                }
                if (result > 1)
                {
                    if (obValues != null)
                    {
                        anc.OBEncounterId = obValues.OBEncounterId;
                        var respose = await this.UpdateAsync(anc);
                    }
                    else
                    {
                        var respose = await this.AddAsync(anc);
                    }
                }
                var updateAppoint = "";
                if (model.IsAdmission)
                {
                    updateAppoint = $@"update ""ObEncounter"" set ""ANCCardGenerationId""={result} where ""AdmissionId""={model.AppointmentId}";
                }
                else
                {
                    updateAppoint = $@"update ""ObEncounter"" set ""ANCCardGenerationId""={result} where ""AppointmentId""={model.AppointmentId}";
                }
                await this.unitOfWork.Current.ExecuteAsync(updateAppoint);

                return result;
            }

        }

        public async Task<ANCCardGenerationModel> FetchAncCardAsync(ANCCardGenerationModel model)
        {

            var ancReords = new ANCCardGenerationModel();
            var ancQuerry = "";
            if (model.IsAdmission)
            {
                ancQuerry = $@"select * from ""ObEncounter"" where ""AdmissionId""={model.AppointmentId}";

            }
            else
            {
                ancQuerry = $@"select * from ""ObEncounter"" where ""AppointmentId""={model.AppointmentId}";

            }
            var obRecords = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(ancQuerry);
            if (obRecords != null && obRecords.ANCCardGenerationId != null)
            {
                var query = $@"select * from ""ANCCardGeneration"" where ""ANCCardGenerationId""={obRecords.ANCCardGenerationId}";
                ancReords = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ANCCardGenerationModel>(query);
            }
            return ancReords;
        }

        public Task<int> ModifyStatusAsync(int patientId)
        {
            var query = $@"UPDATE ""ANCCardGeneration"" SET ""Active"" = false  WHERE ""PatientId""= {patientId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<IEnumerable<OrderPrescriptions>> FetchOrderPrescription(int patientId, string encounterType)
        {
            var appointmentsQuery = $@"select ""AppointmentDate"", ""AppointmentTime"", ""AppointmentId"", pr.""FullName"" as ""ProviderName""
                        from ""Appointment"" AP
                        JOIN ""Provider"" pr on pr.""ProviderId""=AP.""ProviderId""
                        where ""PatientId""={patientId} ";
            var numberOfAppointments = await this.unitOfWork.Current.QueryAsync<ANCCardGenerationModel>(appointmentsQuery);
            var orders = new List<OrderPrescriptions>();
            foreach (var item in numberOfAppointments)
            {
                var orderQuery = "";
                switch (encounterType)
                {
                    case "ob-encounter":
                    orderQuery = $@"select ""AppointmentId"", ""OrderPrescription"" from ""ObEncounter"" where ""AppointmentId""={item.AppointmentId}";
                        break;
                    case "gyn-encounter":
                        orderQuery = $@"select ""AppointmentId"", ""OrderPrescription"" from ""GynEncounter"" where ""AppointmentId""={item.AppointmentId}";
                        break;
                    case "pediatric-encounter":
                        orderQuery = $@"select ""AppointmentId"", ""OrderPrescription"" from ""PediatricEncounter"" where ""AppointmentId""={item.AppointmentId}";
                        break;
                }
                var ordersValue = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<OrderPrescriptions>(orderQuery);
                if (ordersValue != null)
                {
                    var labModel = new PatientMedicationHeaderModel();
                    labModel.AppointmentId = item.AppointmentId;
                    labModel.IsAdmission = false;
                    var labRecords = await this.patientEncounterService.FetchPatientLabsAsync(labModel);
                    var medicatonRecords = await this.patientEncounterService.FetchPatientMedication(labModel);
                    ordersValue.Labs = labRecords != null ? labRecords : null;
                    ordersValue.Medications = medicatonRecords != null ? medicatonRecords : null;
                    if (ordersValue != null && ordersValue.OrderPrescription != null)
                    {
                        ordersValue.EncryptedAppointmentId = this.aesHelper.Encode(item.AppointmentId.ToString());
                        ordersValue.AppointmentDate = item.AppointmentDate;
                        ordersValue.AppointmentTime = item.AppointmentTime;
                        ordersValue.ProviderName = item.ProviderName;

                        orders.Add(ordersValue);
                    }
                }
                    
            }
            return orders;
        }

        public Task<int> ModifyEncounterStatus(int appointmentId)
        {
            var query = $@"UPDATE ""ObEncounter"" SET ""IsAppointmentClosed"" = true  WHERE ""AppointmentId""= {appointmentId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<IEnumerable<ICDValuesModel>> FetchICDValues(ICDValuesModel model)
        {
            var query = "";
            if (model.Usable != null)
            {
                var where = " WHERE  ";
                string[] c = model.Usable.Select(s => s.ToString()).ToArray();
                var num = Convert.ToChar(c[1]);
                if (num >= '0' && num < '9')
                {
                    where += $@"""Code"" ilike '%{model.Usable}%'";
                }
                else
                {
                    where += $@"""Usable"" ilike '%{model.Usable}%'";
                }
                query = $@"select * from ""ICDValues""  {where}  ";
            }
            else
            {
                query = $@"select * from ""ICDValues""   order by 1 limit 10";
            }

            return await this.unitOfWork.Current.QueryAsync<ICDValuesModel>(query);
        }

        public async Task<ObEncounterResource> FindOb(int appointmentId, OBEncounterType type, bool isAdmission)
        {
            try
            {
                var obEncounter = isAdmission
                                   ? await this.unitOfWork.ObEncounters.FindAsync(m => m.AdmissionId == appointmentId)
                                   : await this.unitOfWork.ObEncounters.FindAsync(m => m.AppointmentId == appointmentId);


                var obEncounterResource = new ObEncounterResource
                {
                    AppointmentId = appointmentId,
                    OBEncounterId = null,
                    JsonString = null
                };

                if (obEncounter != null)
                {
                    obEncounterResource.OBEncounterId = obEncounter.OBEncounterId;
                    switch (type)
                    {

                        case OBEncounterType.OrderPrescription:
                            obEncounterResource.JsonString = obEncounter.OrderPrescription;
                            break;
                        case OBEncounterType.Measure:
                            obEncounterResource.JsonString = obEncounter.Measure;
                            break;
                    }
                }

                return obEncounterResource;
            }
            catch (Exception ex)
            {
                throw;
            }

        }

        public async Task<int> getApppointmentId(int appointmentId, bool isAdmission)
        {
            var id = 0;
            id = isAdmission ? await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AdmissionId"" = {appointmentId}") :
            await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""ObEncounter"" WHERE ""AppointmentId"" = {appointmentId}");

            return id;
        }

        public async Task<IEnumerable<ReferralFormModel>> FetchCrossConsultation(ReferralFormModel model)
        {

            var where = $@" WHERE" ; 
            if (model.PatientId != null)
            {
                where += $@"  RF.""PatientId"" = '{model.PatientId}'";
            }
            if (model.AppointmentId != null) 
            {
                where += $@"  RF.""AppointmentId"" = '{model.AppointmentId}'";
            }
            if (model.ProviderId != null)
            {
                where += $@"  RF.""ReferralDoctorId"" = '{model.ProviderId}' AND  RF.""Active""=true ";
            }
            var query = $@"select RF.""ReferralFormId"" ,RF.""ReferralDoctor"" , RF.""Reason"" ,RF.""RequiredDate"" ,RF.""Time"" , RF.""CreatedDate"" ,RF.""ConsultantDoctor"",RF.""Opinion"" ,RF.""Active"" ,	RF.""AppointmentId"" ,RF.""ProviderId"",RF.""ReferralDoctorId"" ,RF.""PatientId"", p.""FullName"" as ""PatientName""
                        from ""ReferralForm"" RF
                        join ""Patient"" p on p.""PatientId""=RF.""PatientId""
                        {where} ";
            return await this.unitOfWork.Current.QueryAsync<ReferralFormModel>(query);

        }

        public async Task<IEnumerable<LabBookingModel>> fetchlabBookingHeader(int patientId)
        {
            var query = $@"select nlbd.""NewLabBookingDetailId"",nlbh.""NewLabBookingHeaderId"",lmd.""TestName"" from ""NewLabBookingHeader"" nlbh
                        join  ""NewLabBookingDetail"" nlbd on nlbd.""NewLabBookingHeaderId"" = nlbh.""NewLabBookingHeaderId""
                        join ""LabMainDetail"" lmd on lmd.""LabMainDetailId"" = nlbd.""LabMainDetailId""
                        join ""LabBookingStatus"" lbs on lbs.""LabBookingStatusId"" = nlbd.""LabBookingStatusId"" 
                        where nlbh.""PatientId"" = {patientId} and lbs.""Status"" = 'Verified'";
            return await this.unitOfWork.Current.QueryAsync<LabBookingModel>(query);
        }

        public async Task<int> FetchVisitNoAsync(int patientId)
        {
            var query = $@"select count(*) from ""ObEncounter"" where ""PatientId""={patientId} and  ""Active""=true";
            return await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(query);

        }

        public async Task<int> InsertReferralForm(ReferralFormModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""ReferralForm"" where  ""AppointmentId""= '{model.AppointmentId}'");
            var referralForm = new ReferralForm();
            referralForm.ReferralDoctor = model.ReferralDoctor;
            referralForm.Reason = model.Reason;
            referralForm.RequiredDate = model.RequiredDate;
            referralForm.Time = model.Time;
            referralForm.ConsultantDoctor = model.ConsultantDoctor;
            referralForm.AppointmentId = (int)model.AppointmentId;
            referralForm.CreatedDate = DateTime.Now;
            referralForm.Active = model.Active;
            referralForm.ProviderId = model.ProviderId;
            referralForm.PatientId = model.PatientId;
            referralForm.Opinion = model.Opinion;
            referralForm.ReferralDoctorId = model.ReferralDoctorId;
            if (checkIf > 0)
            {
                var records = this.unitOfWork.ReferralForms.Find(s => s.AppointmentId == model.AppointmentId);
                records.Time = model.Time;
                records.Opinion = model.Opinion;
                return await this.unitOfWork.ReferralForms.UpdateAsync(records);
            }

            return await this.unitOfWork.ReferralForms.InsertAsync(referralForm);


        }

        public async Task<ANCCardGenerationModel> FetchPatientAncCardAsync(ANCCardGenerationModel model)
        {
            var where = $@" where 1=1 and ""Active""=true";
            if (model.PatientId != 0)
            {
                where += $@" and ""PatientId""={model.PatientId}";
            }
            var query = $@"select * from ""ANCCardGeneration"" {where}";
            return await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ANCCardGenerationModel>(query);
        }

        public async Task<IEnumerable<ObEncounterModel>> FetchFullTrascriptList(int patientId)
        {
             var query = $@"select apt.""AppointmentDate"", ob.""AppointmentId"", pr.""FullName"" as ""ProviderName"", ""AnaesthesiaRecord""
                    from ""ObEncounter"" ob
                    join ""Appointment"" apt on apt.""AppointmentId""=ob.""AppointmentId""
                    join ""Provider"" pr on pr.""ProviderId""=apt.""ProviderId""
                    where ob.""PatientId""={patientId} ";
                return await this.unitOfWork.Current.QueryAsync<ObEncounterModel>(query);

            
           
        }

        public async Task<IEnumerable<LabParameters>> FetchLabParameters(int labMainDetailId)
        {
            var query = $@"select lmdt.""LabTemplateHeaderId"",lch.""LabComponentHeaderId"", lch.""ComponentName"", lph.""LabParameterHeaderId"",
                        lph.""ParameterName"", lph.""DisplayName"",lph.""MachineId"",lph.""MachineParameterName""
                        from ""LabMainDetail"" lmd
                        join ""LabMainDetailTemplate"" lmdt on lmdt.""LabMainDetailId"" = lmd.""LabMainDetailId"" 
                        join ""LabTemplateHeader"" lth on lth.""LabTemplateHeaderId"" = lmdt.""LabTemplateHeaderId""
                        join ""LabTemplateDetail"" ltd on ltd.""LabTemplateHeaderId"" = lth.""LabTemplateHeaderId"" 
                        join ""LabComponentHeader"" lch on lch.""LabComponentHeaderId"" = ltd.""LabComponentHeaderId"" 
                        join ""LabComponentDetail"" lcd on lcd.""LabComponentHeaderId"" = lch.""LabComponentHeaderId"" 
                        join ""LabParameterHeader"" lph on lph.""LabParameterHeaderId"" = lcd.""LabParameterHeaderId""
                        where lmd.""LabMainDetailId"" = {labMainDetailId}
                        union  all
                        select lmdt.""LabTemplateHeaderId"",null as ""LabComponentHeaderId"",null, lph.""LabParameterHeaderId"",
                        lph.""ParameterName"", lph.""DisplayName"",lph.""MachineId"",lph.""MachineParameterName""
                        from ""LabMainDetail"" lmd
                        join ""LabMainDetailTemplate"" lmdt on lmdt.""LabMainDetailId"" = lmd.""LabMainDetailId"" 
                        join ""LabTemplateHeader"" lth on lth.""LabTemplateHeaderId"" = lmdt.""LabTemplateHeaderId""
                        join ""LabTemplateDetail"" ltd on ltd.""LabTemplateHeaderId"" = lth.""LabTemplateHeaderId"" 
                        join ""LabParameterHeader"" lph on lph.""LabParameterHeaderId"" = ltd.""LabParameterHeaderId""
                        where lmd.""LabMainDetailId"" = {labMainDetailId}";
            return await this.unitOfWork.Current.QueryAsync<LabParameters>(query);
        }

        public async Task<ObEncounterModel> FindEncounterDataAsync(int appointmentId, bool isAdmission)
        {
            var  query = isAdmission ? $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where   ob.""AdmissionId""={appointmentId} order by 1 desc " :
                     $@"select * from ""ObEncounter"" ob 
                        left join ""CommonEncounter"" CE on CE.""PatientId""=ob.""PatientId""
                        where  ob.""AppointmentId""={appointmentId} order by 1 desc ";
            var response = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<ObEncounterModel>(query);
            if (response == null) return new ObEncounterModel(); return response;
        }
    }
}
