namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    using Domain.Services;

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Npgsql;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.UserModels.Filters;

    using Utilities;
    using Hims.Shared.Library.Enums;
    using Hims.Api.Models;

    /// <summary>
    /// The provider encounters controller.
    /// </summary>
    [Route("api/providerEncounter")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class ProviderEncounterController : BaseController
    {
        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IProviderEncounterService providerEncounterServices;

        /// <summary>
        /// The audit log services.
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <inheritdoc />
        public ProviderEncounterController(IProviderEncounterService providerEncounterServices, IAuditLogService auditLogServices) { this.providerEncounterServices = providerEncounterServices; this.auditLogServices = auditLogServices; }

        /// <summary>
        /// The add async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("add")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(string), 409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> AddAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            try
            {
                model = (ProviderEncounterModel)EmptyFilter.Handler(model);
                var value = await this.providerEncounterServices.AddAsync(model);
                string type;
                if (value > 0)
                {
                    var auditLogModel = new AuditLogModel
                    {
                        AccountId = model.CreatedBy,
                        LogTypeId = (int)LogTypes.ProviderEncounters,
                        LogFrom = (int)AccountType.Administrator,
                        LogDate = DateTime.UtcNow,
                        LogDescription = $"{model.FullName} Provider has been assigned successfully.",
                        LocationId = Convert.ToInt32(header.LocationId)
                    };
                    await this.auditLogServices.LogAsync(auditLogModel);
                }
                switch (value)
                {
                    case -1:
                        var response = await this.providerEncounterServices.UpdateAsync(model);
                        switch (response)
                        {
                            case 1:
                                type = "GeneralAdvices";
                                break;
                            case 2:
                                type = "Icd Codes";
                                break;
                            case 3:
                                type = "Lab Order Values";
                                break;
                            case 4:
                                type = "Radiology Values";
                                break;
                            case 5:
                                type = "Allergies";
                                break;
                            case 6:
                                type = "Reactions";
                                break;
                            case 7:
                                type = "Hospitalizations";
                                break;
                            case 8:
                                type = "Initials";
                                break;
                            case 9:
                                type = "PCares";
                                break;
                            case 10:
                                type = "Sites";
                                break;
                            case 11:
                                type = "Vaccines";
                                break;
                            default:
                                type = "Provider Encounters";
                                break;
                        }
                        if (response != 0)
                        {
                            var auditLogModel = new AuditLogModel
                            {
                                AccountId = model.ModifiedBy,
                                LogTypeId = (int)LogTypes.ProviderEncounters,
                                LogFrom = (int)AccountType.Administrator,
                                LogDate = DateTime.UtcNow,
                                LogDescription = $"{model.FullName} Provider has been updated {type} successfully.",
                                LocationId = Convert.ToInt32(header.LocationId)
                            };
                            await this.auditLogServices.LogAsync(auditLogModel);
                            return this.Success($"{type} has been updated successfully.");
                        }
                        return this.ServerError();
                    default:
                        return this.Success("Provider Encounter has been Added successfully.");
                }
            }
            catch (Exception msg)
            {
                return this.Conflict(msg);
            }
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-general-advices")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllGeneralAdvicesAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllGeneralAdvicesAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all general advices successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-icd-codes")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllIcdCodeAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllIcdCodeAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all icd codes successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-lab-order-value")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllLabOrderValueAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllLabOrderValueAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all labordervalue successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-radiology-value")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllRadiologyValueAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllRadiologyValueAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all radiologyvalue successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-allergies")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllAllergiesAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllAllergiesAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all allergies successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-reactions")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllReactionsAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllReactionsAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all reactions successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-hospitalization")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllHospitalizationAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllHospitalizationAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all hospitalizations successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-initials")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllInitialsAsync([FromBody] ProviderEncounterModel model, [FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllInitialsAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all initials successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-pcare")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllPCareAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllPCareAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all PCares successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-site")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllSiteAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllSiteAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all Sites successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update-unassign-all-vaccine")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UnAssignAllVaccineAsync([FromBody] ProviderEncounterModel model,[FromHeader] LocationHeader header)
        {
            var response = await this.providerEncounterServices.UnAssignAllVaccineAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Something Wrong");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.FullName} Provider has been updated and unassigned all Vaccines successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("Provider Encounters has been updated successfully.");
        }

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch")]
        [ProducesResponseType(typeof(IEnumerable<ProviderEncounterModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<IEnumerable<ProviderEncounterModel>> FetchAsync([FromBody] ProviderEncounterFilterModel model)
        {
            var records = await this.providerEncounterServices.FetchAsync(model);
            var providerEncounterModel = new List<ProviderEncounterModel>();
            if (records != null)
            {
                foreach (var record in records)
                {
                    var providerEncounterModels = new ProviderEncounterModel
                    {
                        ProviderGeneralAdviceId = record.ProviderGeneralAdviceId,
                        GeneralAdviceIds = record.GeneralAdviceIds,
                        IcdIds = record.IcdIds,
                        FullName = record.FullName,
                        LabOrderValueIds = record.LabOrderValueIds,
                        RadiologyValueIds = record.RadiologyValueIds,
                        AllergyIds = record.AllergyIds,
                        HospitalizationIds = record.HospitalizationIds,
                        ReactionIds = record.ReactionIds,
                        PCareIds = record.PCareIds,
                        InitialIds = record.InitialIds,
                        SiteIds = record.SiteIds,
                        VaccineIds = record.VaccineIds,
                        ProviderId = record.ProviderId,
                        CreatedBy = record.CreatedBy,
                        ModifiedBy = record.ModifiedBy,
                        ModifiedDate = record.ModifiedDate,
                        CreatedDate = record.CreatedDate
                    };
                    providerEncounterModel.Add(providerEncounterModels);
                }

                return providerEncounterModel;
            }

            return null;
        }

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="providerId">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-provider-encounter")]
        [ProducesResponseType(typeof(ProviderEncounterModel), 200)]
        [ProducesResponseType(500)]
        public ProviderEncounterModel FetchProviderEncounterAsync([FromBody] int providerId)
        {
            var records = this.providerEncounterServices.FetchProviderEncounterAsync(providerId);
            return records;
        }

        /// <summary>
        /// The fetch radiology value async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-radiology-values")]
        [ProducesResponseType(typeof(List<RadiologyValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchRadiologyValueAsync([FromBody] RadiologyValueFilterModel model)
        {
            model = (RadiologyValueFilterModel)EmptyFilter.Handler(model);
            var radiologyValues = await this.providerEncounterServices.FetchRadiologyValueAsync(model);
            return this.Success(radiologyValues);
        }

        /// <summary>
        /// The fetch radiology value async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-allergies")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchAllergiesAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchAllergiesAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch reactions async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-reactions")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchReactionsAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchReactionsAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch hospitalizations async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-hospitalizations")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchHospitalizationsAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchHospitalizationsAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch initials async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-initials")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchInitialsAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchInitialsAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch pcares async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-pcares")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchPCaresAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchPCaresAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch sites async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-sites")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchSitesAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchSitesAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The fetch vaccines async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch-vaccines")]
        [ProducesResponseType(typeof(List<LookupValueModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchVaccinesAsync([FromBody] LookUpValueFilterModel model)
        {
            model = (LookUpValueFilterModel)EmptyFilter.Handler(model);
            var lookupValues = await this.providerEncounterServices.FetchVaccinesAsync(model);
            return this.Success(lookupValues);
        }

        /// <summary>
        /// The delete service.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider Encounter deleted successfully.
        /// - 409 - Provider Encounter can not be deleted.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [Authorize]
        [Route("delete")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> DeleteProviderEncounterAsync([FromBody] ProviderEncounterModel model,[FromHeader]LocationHeader header)
        {
            try
            {
                model = (ProviderEncounterModel)EmptyFilter.Handler(model);
                var response = await this.providerEncounterServices.DeleteProviderEncounterAsync(model.ProviderGeneralAdviceId);
                if (response == 0)
                {
                    return this.ServerError();
                }
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.ModifiedBy,
                    LogTypeId = (int)LogTypes.ProviderEncounters,
                    LogFrom = (int)AccountType.Administrator,
                    LogDate = DateTime.UtcNow,
                    LogDescription = $"{model.FullName} Provider has been deleted successfully.",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
                return this.Success("Provider Encounters has been deleted successfully.");
            }
            catch (NpgsqlException exception)
            {
                if (exception.Message.Contains("violates foreign key constraint"))
                {
                    return this.Conflict("Provider Encounters can't be deleted. Please contact administrator.");
                }

                return this.ServerError();
            }
        }

        /// <summary>
        /// The update lookupvalues.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - lookupvalue updated successfully.
        /// - 409 - lookupvalue already exist.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPut]
        [Route("update-lookup-value")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UpdateLookupValueAsync([FromBody] LookupValueModel model,[FromHeader] LocationHeader header)
        {
            model = (LookupValueModel)EmptyFilter.Handler(model);
            var response = await this.providerEncounterServices.UpdateLookupValueAsync(model);
            switch (response)
            {
                case -1:
                    return this.Conflict("Given LookupValue name has already been exists with us.");
                case 0:
                    return this.ServerError();
            }
            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.ProviderEncounters,
                LogFrom = (int)AccountType.Administrator,
                LogDate = DateTime.UtcNow,
                LogDescription = $"{model.Name} LookupValue has been updated successfully.",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return this.Success("LookupValue has been updated successfully.");
        }
    }
}