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

    using Domain.Services;
    using Domain.Configurations;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.UserModels.Laboratory;
    using System.Collections.Generic;

    using Utilities;
    using Hims.Shared.Library.Enums;
    using System;
    using System.Linq;
    using Hims.Domain.Helpers;
    using Hims.Shared.UserModels.Common;
    using Hims.Shared.UserModels.ServiceOrder;
    using Senders;
    using Hims.Api.Models;

    /// <inheritdoc />
    [Authorize]
    [Route("api/laboratory")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class LaboratoryController : BaseController
    {
        /// <summary>
        /// The laboratory service.
        /// </summary>
        private readonly ILaboratoryService laboratoryService;

        /// <summary>
        /// The laboratory package service.
        /// </summary>
        private readonly ILaboratoryPackageService laboratoryPackageService;

        /// <summary>
        /// The laboratory department service.
        /// </summary>
        private readonly ILabDepartmentService laboratoryDepartmentService;

        /// <summary>
        /// The laboratory service.
        /// </summary>
        private readonly ILabLogService labLogService;

        /// <summary>
        /// The AES helper.
        /// </summary>
        private readonly IAESHelper aesHelper;

        /// <summary>
        /// The SMS sender.
        /// </summary>
        private readonly ISMSSender smsSender;

        /// <summary>
        /// The Application configuration.
        /// </summary>
        private readonly IApplicationConfiguration applicationConfiguration;

        /// <summary>
        /// The web notification service.
        /// </summary>
        private readonly IWebNotificationService webNotificationService;

        /// <inheritdoc />
        public LaboratoryController(ILaboratoryService laboratoryService, ILaboratoryPackageService laboratoryPackageService, ILabLogService labLogService, IAESHelper aesHelper, IApplicationConfiguration applicationConfiguration, ISMSSender smsSender, ILabDepartmentService laboratoryDepartmentService, IWebNotificationService webNotificationService)
        {
            this.laboratoryService = laboratoryService;
            this.laboratoryPackageService = laboratoryPackageService;
            this.labLogService = labLogService;
            this.aesHelper = aesHelper;
            this.applicationConfiguration = applicationConfiguration;
            this.smsSender = smsSender;
            this.laboratoryDepartmentService = laboratoryDepartmentService;
            this.webNotificationService = webNotificationService;
        }

        /// <summary>
        /// The insert lab units async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("create-unit")]
        public async Task<ActionResult> InsertLabUnitsAsync([FromBody] LookupValueModel model, [FromHeader] LocationHeader header)
        {
            model = (LookupValueModel)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.CreateUnitAsync(model);
            var locationId = Convert.ToInt32(header.LocationId);
            try
            {

                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.LoginAccountId,
                        LabLogTypeId = (int)LabLogTypes.Lab_Masters_Unit,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LocationId = locationId,
                        LogDescription = $@"'{model.AccountFullName}' has added new unit '{model.Name}'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                //ignore
            }
            return this.Success(response);

        }

        /// <summary>
        /// The modify labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("modify-lab")]
        public async Task<ActionResult> ModifyLabsAsync([FromBody] LabHeaderModel model, [FromHeader] LocationHeader header)
        {
            model = (LabHeaderModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.ModifyLabAsync(model);
            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.CreatedBy,
                        LabLogTypeId = (int)LabLogTypes.Lab_Masters_Lab,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LocationId = model.LocationId,
                        LogDescription = model.LabHeaderId > 0 ? $@"'{model.CreatedByName}' has Updated Lab Name: '{model.LabName}' Lab Code: '{model.LabCode}' Successfully.'" : $@"{model.CreatedByName}' has Added New Lab: '{model.LabName}' Lab Code: '{model.LabCode}' Successfully.'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// The modify labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("modify-import-lab")]
        public async Task<ActionResult> ModifyImportLabsAsync([FromBody] LabImportModel model, [FromHeader] LocationHeader header)
        {
            model = (LabImportModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.ModifyImportLabAsync(model);
            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.CreatedBy,
                        LabLogTypeId = (int)LabLogTypes.Lab_Masters_Lab,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LocationId = model.LocationId,
                        LogDescription = model.LabHeaderId > 0 ? $@"'{model.CreatedByName}' has Updated Lab Name: '{model.LabName}' Lab Code: '{model.LabCode}' Successfully.'" : $@"{model.CreatedByName}' has Added New Lab: '{model.LabName}' Lab Code: '{model.LabCode}' Successfully.'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// The fetch labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-lab")]
        public async Task<ActionResult> FetchLabsAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            var models = model ?? new RequestLaboratory();
            models.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.FetchAllLabs(models);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-lab-import")]
        public async Task<ActionResult> FetchLabsImportAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            var models = model ?? new RequestLaboratory();
            models.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.FetchImportLabs(models);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch labs details async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet]
        [Route("fetch-lab-detail")]
        public async Task<ActionResult> FetchLabsDetailsAsync(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return this.BadRequest("Id is required");
            }
            var response = await this.laboratoryService.FetchLabDetails(int.Parse(id));
            return this.Success(response);
        }

        // todo: fetch-lab-location-charges

        /// <summary>
        /// Fetches the lab location charges asynchronous.
        /// </summary>
        /// <param name="labHeaderId">The lab header identifier.</param>
        /// <param name="header">The header.</param>
        /// <returns></returns>
        [HttpGet]
        [Route("fetch-lab-location-charges")]
        public async Task<ActionResult> FetchLabLocationChargesAsync(int labHeaderId, [FromHeader] LocationHeader header)
        {
            int locationId = Convert.ToInt32(header.LocationId);
            if (locationId == 0)
            {
                return this.BadRequest("Id is required");
            }
            var response = await this.laboratoryService.FetchLabLocationCharges(locationId, labHeaderId);
            return this.Success(response);
        }

        /// <summary>
        /// The delete labs async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="LoginAccountId"></param>
        /// <param name="LoginRoleId"></param>
        /// <param name="LoginFullName"></param>
        /// <param name="LabName"></param>
        /// <param name="LabCode"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet]
        [Route("delete-lab")]
        public async Task<ActionResult> DeleteLabsAsync(string id, int LoginAccountId, int LoginRoleId, string LoginFullName, string LabName, string LabCode, [FromHeader] LocationHeader header)
        {
            try
            {
                if (string.IsNullOrEmpty(id))
                {
                    return this.BadRequest("Id is required");
                }

                if (string.IsNullOrEmpty(header.LocationId))
                {
                    return this.BadRequest("Location Id is required");
                }
                var locationId = int.Parse(header.LocationId);

                var response = await this.laboratoryService.DeleteLabsAsync(int.Parse(id), locationId);

                try
                {
                    if (response > 0)
                    {
                        var labLogModel = new LabLogModel
                        {
                            AccountId = LoginAccountId,
                            LabLogTypeId = (int)LabLogTypes.Lab_Masters_Lab,
                            LogFrom = (short)LoginRoleId,
                            LogDate = DateTime.UtcNow,
                            LogDescription = $@"'{LoginFullName}' has deleted the Lab Name:'{LabName}' Lab Code:'{LabCode}' Successfully.",
                            LocationId = locationId
                        };
                        await this.labLogService.LogAsync(labLogModel);
                    }
                }
                catch (Exception ex)
                {
                    //audit
                }
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("update or delete on table \"LabDetail\" violates foreign key constraint \"LabPatientParameter_LabDetailId_fkey\" on table \"LabPatientParameter\""))
                {
                    return this.Success(new GenericResponse
                    {
                        Status = GenericStatus.Error,
                        Message = ex.Message
                    });
                }
                throw;
            }

        }

        /// <summary>
        /// The add patient lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("add-lab-booking")]
        public async Task<ActionResult> AddPatientLabBookingAsync([FromBody] AddBooking model, [FromHeader] LocationHeader header)
        {
            model = (AddBooking)EmptyFilter.Handler(model);

            model.LocationId = Convert.ToInt32(header.LocationId);

            //var labDetails = (await this.laboratoryService.FetchLab(model.LabBookingPackageDetailId)).ToList();
            var response = await this.laboratoryService.AddPatientLabBooking(model, new List<InsertLabServiceHelperModel>());
            if (response == -5)
            {
                return this.Success(response);
            }

            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.CreatedBy,
                        LabLogTypeId = (int)LabLogTypes.Lab_BookingLab,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.Now,
                        LogDescription = $@"'{model.RoleName}' has added Lab Booking for Patient '{model.PatientName}' '{model.UMRNo}' Successfully.",
                        LocationId = model.LocationId
                    };
                    await this.labLogService.LogAsync(labLogModel);

                    if (model.AppointmentId != null)
                    {

                        await this.webNotificationService.UpdateReadStatus((int)model.AppointmentId, (int)WebNotificationTypes.Labratory);
                    }
                }
            }
            catch (Exception)
            {
                // ignore
            }

            return response > 0 ? this.Success(response) : this.ServerError();
        }


        /// <summary>
        /// The fetch patient lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-lab-bill-detail")]
        public async Task<ActionResult> FetchPatientLabBookingAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.FetchLabHeadersBasedOnCondition(model.LabBookingHeaderId, model.BillNumber);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch lab headers async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("fetch-lab-booking-header")]
        public async Task<ActionResult> FetchLabHeadersAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.FetchLabBookingHeaders(model);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch lab headers async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("fetch-sample-status")]
        public async Task<ActionResult> FetchSampleStatusAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            if (header != null && !string.IsNullOrEmpty(header.LocationId))
            {
                model.LocationId = Convert.ToInt32(header.LocationId);
            }
            var response = await this.laboratoryService.FetchSampleStatus(model);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch lab headers with lab details async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch-lab-booking-header-with-detail")]
        public async Task<ActionResult> FetchLabHeadersWithLabDetailsAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            if (header != null && !string.IsNullOrEmpty(header.LocationId))
            {
                model.LocationId = Convert.ToInt32(header.LocationId);
            }
            var response = await this.laboratoryService.FetchLabBookingHeaders(model);

            foreach (var labHeader in response)
            {
                labHeader.LabDetail = new List<LabBookingDetailModel>();
                var detail = await this.laboratoryService.FetchBookingLabDetailsWithPackageDataAsync(labHeader.LabBookingHeaderId, labHeader);
                labHeader.LabDetail.AddRange(detail);
                labHeader.Limit = 3;
                labHeader.TotalElements = labHeader.LabDetail.Count;

                foreach (var labDetail in detail)
                {
                    if (labDetail.LabPackageId > 0)
                    {
                        labDetail.LabsInPackage = new List<BookingPackageLaboratoryModel>();
                        var labs = await this.laboratoryPackageService.FetchLabsInsidePackageBookingAsync(labDetail.LabBookingDetailId, null);
                        labDetail.LabsInPackage.AddRange(labs);
                    }
                }

            }

            return this.Success(response);
        }

        /// <summary>
        /// The Fetch lab detail async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpGet]
        [Route("fetch-lab-booking-detail")]
        public async Task<ActionResult> FetchLabDetailAsync(string? id, string? status, LabBookingDetailModel model)
        {
            //if (string.IsNullOrEmpty(id))
            //{
            //return this.BadRequest("Id is required");
            //}
            try
            {
                var response = await this.laboratoryService.FetchBookingLabDetails(id, status, model);
                return this.Success(response);
            }
            catch (Exception ex)
            {
                throw;
            }
        }


        /// <summary>
        /// The update lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("update-lab-status")]
        public async Task<ActionResult> UpdateLabBookingAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = !string.IsNullOrEmpty(model.UpdateAll) ? await this.laboratoryService.UpdateBookingLabDetailStatusAll((int)model.LabBookingHeaderId, model.Status, (int)model.AccountId) : await this.laboratoryService.UpdateBookingLabDetailStatus((int)model.LabBookingDetailId, model.Status, (int)model.AccountId);

            try
            {
                var labLogModel = new LabLogModel
                {
                    AccountId = model.AccountId,
                    LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.Now,
                    LocationId = (int)model.LocationId,
                    LogDescription = (model.UpdateAll != null) ? $@"'{model.CreatedByName}' has Collected all Samples for the Bill number '{model.BillNumber}'." : $@"'{model.CreatedByName}' has Collected Samples for Lab: '{model.LabName}' the Bill number '{model.BillNumber}'."
                };
                await this.labLogService.LogAsync(labLogModel);
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// The update lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("add-bulk-lab-parameters")]
        public async Task<ActionResult> AddBulkPatientParametersAsync([FromBody] List<LabPatientParameterModel> model, [FromHeader] LocationHeader header)
        {
            if (model.Count == 0)
            {
                return this.BadRequest("Invalid input.");
            }
            var locationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.InsertBulkPatientParameterAsync(model);

            try
            {
                var labDetails = new LabHeaderModel();
                if (model[0].LabBookingPackageDetailId != null)
                {
                    labDetails = await this.laboratoryService.FetchLab((int)model[0].LabBookingPackageDetailId);
                }
                //var labDetails = await this.laboratoryService.FetchLab((int)model[0].LabBookingPackageDetailId);
                var labLogModel = new LabLogModel
                {
                    AccountId = model[0].TypedBy,
                    LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
                    LogFrom = (short)model[0].LoginRoleId,
                    LogDate = DateTime.Now,
                    LocationId = locationId,
                    LogDescription = model[0].LabBookingPackageDetailId != null ? $@"'{model[0].CreatedByName}' Added Parameters for the Lab '{labDetails.LabName}' under Bill number '{model[0].BillNumber}' Successfully." : $@"'{model[0].CreatedByName}' Added Parameters for the lab '{model[0].LabName}' under Bill number '{model[0].BillNumber}' Successfully."
                    //LogDescription = model[0].LabBookingPackageDetailId != null ? $@"'{model[0].CreatedByName}' Added Parameters for the lab '{labDetails.LabName}' in the Package Name '{model[0].PackageName}' '{model[0].BillNumber}' Successfully." : $@"'{model[0].CreatedByName}' Added Parameters for the Lab '{model[0].LabName}' '{model[0].BillNumber}' Successfully."
                };
                await this.labLogService.LogAsync(labLogModel);
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// The booking lab report main async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("lab-report-main")]
        public async Task<ActionResult> BookingLabReportMainAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.FetchLabReportMainDataAsync((int)model.LabBookingDetailId);
            return this.Success(response);
        }

        /// <summary>
        /// The booking lab report test result async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("lab-report-result")]
        public async Task<ActionResult> BookingLabReportTestResultAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.FetchLabResultReportParameterAsync((int)model.LabBookingDetailId);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch lab daily report async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("fetch-lab-daily-report")]
        public async Task<ActionResult> FetchLabDailyReportAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            var models = model ?? new RequestLaboratory();
            models.LocationId = Convert.ToInt32(header.LocationId);
            if (!string.IsNullOrEmpty(models.EncryptedPatientId))
            {
                models.PatientId = Convert.ToInt32(this.aesHelper.Decode(models.EncryptedPatientId));
            }
            var response = await this.laboratoryService.FetchLabDailyReport(models);
            var responseModels = response.ToList();
            if (!string.IsNullOrEmpty(models.EncryptedPatientId) && responseModels.ToArray().Length == 0)
            {
                response = new List<LabDailyReportModel> { new LabDailyReportModel { PatientId = Convert.ToInt32(models.PatientId) } };
                return this.Success(response);
            }
            foreach (var item in responseModels)
            {
                item.EncryptedPatientId = this.aesHelper.Encode(item.PatientId.ToString());
            }
            return this.Success(response);
        }


        /// <summary>
        /// The fetch lab daily report async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("verify-lab-report")]
        public async Task<ActionResult> VerifyLabReportAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model.LocationId = Convert.ToInt32(header.LocationId);
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryService.VerifyLabReportAsync((int)model.LabBookingDetailId, (int)model.AccountId);

            try
            {
                var labLogModel = new LabLogModel
                {
                    AccountId = model.AccountId,
                    LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
                    LogFrom = (short)model.LoginRoleId,
                    LocationId = (int)model.LocationId,
                    LogDate = DateTime.Now,
                    LogDescription = $@" '{model.VerifiedByName}' has verified the Lab '{model.LabName}' under Bill number '{model.BillNumber}'."
                };
                await this.labLogService.LogAsync(labLogModel);
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// The modify lab package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("modify-lab-package")]
        public async Task<ActionResult> ModifyLabPackageAsync([FromBody] AddBooking model, [FromHeader] LocationHeader header)
        {
            model = (AddBooking)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryPackageService.ModifyLabPackage(model);

            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.AccountId,
                        LabLogTypeId = (int)LabLogTypes.Lab_masters_package,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.Now,
                        LocationId = model.LocationId,
                        LogDescription = model.LabPackageId > 0 ? $@" '{model.CreatedByName}' has Updated the Package '{model.Name}' Successfully.'" : $@" '{model.CreatedByName}' has Added the Package '{model.Name}' Successfully.'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// The fetch all lab package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("fetch-all-lab-package")]
        public async Task<ActionResult> FetchAllLabPackageAsync([FromBody] LabPackageModel model, [FromHeader] LocationHeader header)
        {
            model = (LabPackageModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryPackageService.FetchAllLabPackages(model);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch all lab package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("fetch-import-lab-package")]
        public async Task<ActionResult> FetchImportLabPackageAsync([FromBody] LabPackageModel model, [FromHeader] LocationHeader header)
        {
            model = (LabPackageModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryPackageService.FetchImportLabPackages(model);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch lab package detail async.
        /// </summary>
        /// <param name="labPackageId">
        /// The lab package id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpGet]
        [Route("fetch-lab-package-detail")]
        public async Task<ActionResult> FetchLabPackageDetailAsync(int labPackageId)
        {
            if (labPackageId == 0)
            {
                return this.BadRequest();
            }
            var response = await this.laboratoryPackageService.FetchLabPackageDetails(labPackageId);
            return this.Success(response);
        }

        /// <summary>
        /// The lab package delete  async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("delete-lab-package")]
        public async Task<ActionResult> LabPackageDeleteAsync([FromBody] AddBooking model, [FromHeader] LocationHeader header)
        {
            model = (AddBooking)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            try
            {
                var response = await this.laboratoryPackageService.DeleteLabPackageAsync(model.LabPackageId, model.LocationId);

                try
                {
                    if (response > 0)
                    {
                        var labLogModel = new LabLogModel
                        {
                            AccountId = model.AccountId,
                            LabLogTypeId = (int)LabLogTypes.Lab_masters_package,
                            LogFrom = (short)model.LoginRoleId,
                            LogDate = DateTime.Now,
                            LocationId = model.LocationId,
                            LogDescription = $@"'{model.CreatedByName}' has Deleted the Package '{model.PackageName}' Successfully."
                        };
                        await this.labLogService.LogAsync(labLogModel);
                    }
                }
                catch (Exception ex)
                {
                    //audit
                }
                return this.Success(new GenericResponse
                {
                    Status = response > 0 ? GenericStatus.Success : GenericStatus.Warning
                });
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("update or delete on table \"LabPackage\" violates foreign key constraint \"LabBookingDetail_LabPackageId_fkey\" on table \"LabBookingDetail\""))
                {
                    return this.Success(new GenericResponse
                    {
                        Status = GenericStatus.Error,
                        Message = ex.Message
                    });
                }
                throw;

            }
            //return this.Success(response);
        }

        /// <summary>
        /// The fetch lab booking detail for package async.
        /// </summary>
        /// <param name="labBookingHeaderId"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("fetch-lab-booking-detail-for-package")]
        public async Task<ActionResult> FetchLabBookingDetailForPackageAsync(string labBookingHeaderId)
        {
            if (string.IsNullOrEmpty(labBookingHeaderId))
            {
                return this.BadRequest("Id is required");
            }
            var response = await this.laboratoryPackageService.FetchLabBookingPackageAsync(int.Parse(labBookingHeaderId), null);
            foreach (var package in response)
            {
                package.LabsInPackage = new List<BookingPackageLaboratoryModel>();
                var labs = await this.laboratoryPackageService.FetchLabsInsidePackageBookingAsync(package.LabBookingDetailId, null);
                package.LabsInPackage.AddRange(labs);
            }

            return this.Success(response);
        }

        /// <summary>
        /// The update lab sample status for packages async.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        //[HttpPut]
        //[Route("update-booking-package-sample-status")]
        //public async Task<ActionResult> UpdateLabSampleStatusForPackagesAsync([FromBody] RequestLaboratory request, [FromHeader] LocationHeader header)
        //{
        //    request = (RequestLaboratory)EmptyFilter.Handler(request);
        //    request.LocationId = Convert.ToInt32(header.LocationId);
        //    //var labDetails = await this.laboratoryService.FetchLab((int)request.LabBookingPackageDetailId);
        //    var response = request.LabBookingPackageDetailId == null ? await this.laboratoryPackageService.UpdateLabBookingStatusForSample(request) : await this.laboratoryPackageService.UpdateLabBookingPackageStatusForSample(request);

        //    try
        //    {
        //        var labDetails = new LabHeaderModel();
        //        if (request.LabBookingPackageDetailId != null)
        //        {
        //            labDetails = await this.laboratoryService.FetchLab((int)request.LabBookingPackageDetailId);
        //        }
        //        var labLogModel = new LabLogModel
        //        {
        //            AccountId = request.AccountId,
        //            LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
        //            LogFrom = (short)request.LoginRoleId,
        //            LogDate = DateTime.Now,
        //            LocationId = (int)request.LocationId,
        //            LogDescription = request.LabBookingPackageDetailId != null ? $@"'{request.CreatedByName}' has collected samples for Lab: '{labDetails.LabName}' in the package '{request.PackageName}' for Bill number '{request.BillNumber}'." : $@"'{request.CreatedByName}' has collected all Samples for the package '{request.PackageName}' for Bill number '{request.BillNumber}'."
        //            //LogDescription = $@"{request.CreatedByName}' has collected samples for '' the bill number '{request.BillNumber}'"
        //        };
        //        await this.labLogService.LogAsync(labLogModel);
        //    }
        //    catch (Exception) {
        //     // ignore
        //    }

        //    return this.Success(response);
        //}

        /// <summary>
        /// The booking lab report test result package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("lab-report-result-package")]
        public async Task<ActionResult> BookingLabReportTestResultPackageAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryPackageService.FetchLabResultReportParameterPackageAsync((int)model.LabBookingDetailId, (int)model.LabBookingPackageDetailId);
            return this.Success(response);
        }

        /// <summary>
        /// The verify lab booking package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("lab-booking-package-verify")]
        public async Task<ActionResult> VerifyLabBookingPackageAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryPackageService.VerifyLabBookingPackageAsync((int)model.VerifiedBy, model.LabBookingDetailId, model.LabBookingPackageDetailId);

            try
            {
                //var labDetails = await this.laboratoryService.FetchLab((int)model.LabBookingPackageDetailId);
                var labDetails = new LabHeaderModel();
                if (model.LabBookingPackageDetailId != null)
                {
                    labDetails = await this.laboratoryService.FetchLab((int)model.LabBookingPackageDetailId);
                }
                var labLogModel = new LabLogModel
                {
                    AccountId = model.VerifiedBy,
                    LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.Now,
                    LocationId = (int)model.LocationId,
                    //LogDescription = $@"'{model.CreatedByName}' has verified lab test name '{labDetails.LabName}' in the package name'{model.PackageName}' under bill no '{model.BillNumber}'."
                    LogDescription = model.LabBookingDetailId != null ? $@"'{model.CreatedByName}' has verified Package '{model.PackageName}' under bill number '{model.BillNumber}'." : $@"'{model.CreatedByName}' has verified lab test name '{labDetails.LabName}' in the Package name'{model.PackageName}' under bill number '{model.BillNumber}'."
                };
                await this.labLogService.LogAsync(labLogModel);
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// The lab booking package report async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("lab-booking-package-report")]
        public async Task<ActionResult> LabBookingPackageReportAsync([FromBody] RequestLaboratory model)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            var response = await this.laboratoryPackageService.FetchLabBookingPackageAsync((int)model.LabBookingHeaderId, model.LabBookingDetailId);
            foreach (var package in response)
            {
                package.LabsInPackage = new List<BookingPackageLaboratoryModel>();
                var labs = await this.laboratoryPackageService.FetchLabsInsidePackageBookingAsync(package.LabBookingDetailId, model.LabBookingPackageDetailId);
                package.LabsInPackage.AddRange(labs);
                foreach (var individualLab in labs)
                {
                    individualLab.LabsParameters = new List<LabReportParamModel>();
                    var labParameter = await this.laboratoryPackageService.FetchLabResultReportParameterPackageAsync(individualLab.LabBookingDetailId, individualLab.LabBookingPackageDetailId);
                    individualLab.LabsParameters.AddRange(labParameter);
                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// The lab booking package report async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("cancel-lab-booking")]
        public async Task<ActionResult> CancelLabBookingAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.CancelLabBookingAsync((int)model.LabBookingHeaderId, (int)model.AccountId);

            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.AccountId,
                        LabLogTypeId = (int)LabLogTypes.Lab_BookingLab,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LocationId = (int)model.LocationId,
                        LogDescription = $@"'{model.FullName}' has cancelled Lab Booking for Patient '{model.PatientName}' '{model.UMRNo}' of Bill No. '{model.BillNumber}'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// The cancel single lab async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("cancel-single-lab-from-booking")]
        public async Task<ActionResult> CancelSingleLabAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var (headers, response) = await this.laboratoryService.CancelSingleLabFromBooking((int)model.LabBookingHeaderId, (int)model.LabBookingDetailId);

            try
            {
                if (response > 0)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.AccountId,
                        LabLogTypeId = (int)LabLogTypes.Lab_BookingLab,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LocationId = (int)model.LocationId,
                        LogDescription = $@"One lab '{model.LabName}' from bill '{headers.BillNumber}' has been cancelled by '{model.FullName}' for Patient '{model.PatientName}' '{model.UMRNo}'"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// Sends the report message to patients.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("send-lab-report-sms")]
        public async Task<ActionResult> SendReportMessageToPatients([FromBody] RequestLaboratory model, [FromHeader] LocationHeader location)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);

            var link = this.applicationConfiguration.FrontEndLink + $@"/#/lab-reports/package/{model.LabBookingDetailId}";

            if (model.LabBookingHeaderId != null && model.LabBookingDetailId != null)
            {
                var response = (await this.laboratoryService.FetchLabBookingHeaders(model)).ToList();
                model.PatientName = response[0].PatientName;
                model.Mobile = response[0].Mobile;
                link += $@"/{model.LabBookingHeaderId}";
            }
            else if (model.LabBookingHeaderId == null && model.LabBookingDetailId != null)
            {
                var response = await this.laboratoryService.FetchLabReportMainDataAsync((int)model.LabBookingDetailId);
                model.PatientName = response.PatientName;
                model.Mobile = response.Mobile;
                link += "/xyz";
            }

            var (smsResponse, url) = await this.smsSender.SendLabReportSms(model.Mobile, model.PatientName, link);

            try
            {
                if (smsResponse)
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.AccountId,
                        LabLogTypeId = (int)LabLogTypes.SMSReport,
                        LogFrom = model.LoginRoleId > 0 ? (short)model.LoginRoleId : short.Parse(1.ToString()),
                        LogDate = DateTime.UtcNow,
                        LocationId = int.Parse(location.LocationId),
                        LogDescription = $@"Report for lab sended to Patient : <b>{model.PatientName}</b> via sms"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }

            return smsResponse ? this.Success(url) : this.BadRequest(url);
        }

        /// <summary>
        /// Modifies the lab departments asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-lab-department")]
        public async Task<ActionResult> ModifyLabDepartmentsAsync([FromBody] LabDepartmentModel model, [FromHeader] LocationHeader location)
        {
            model = (LabDepartmentModel)EmptyFilter.Handler(model);
            var response = await this.laboratoryDepartmentService.ModifyDepartmentAsync(model);

            string message;
            switch (response)
            {
                case -1:
                case -2:
                    message = "The department name already exists";
                    break;
                case -3:
                    message = "Previous record not found for update";
                    break;
                case int n when n > 0:
                    try
                    {
                        var labLogModel = new LabLogModel
                        {
                            AccountId = model.CreatedBy,
                            LabLogTypeId = (int)LabLogTypes.LabDepartment,
                            LogFrom = model.LoginRoleId > 0 ? (short)model.LoginRoleId : short.Parse(1.ToString()),
                            LogDate = DateTime.UtcNow,
                            LocationId = int.Parse(location.LocationId),
                            LogDescription = $@"Department : <b>{model.DepartmentName}</b> successfully {(model.LabDepartmentId > 0 ? "Updated" : "Added")} into Labs by {model.CreatedByName}"
                        };
                        await this.labLogService.LogAsync(labLogModel);
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                    message = $@"Successfully {(model.LabDepartmentId > 0 ? "updated" : "created")}";
                    break;
                default:
                    message = "Error occured";
                    break;
            }

            return this.Success(message);
        }

        /// <summary>
        /// Fetches the lab departments asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-lab-departments")]
        public async Task<ActionResult> FetchLabDepartmentsAsync([FromBody] LabDepartmentModel model)
        {
            model ??= new LabDepartmentModel();
            var response = await this.laboratoryDepartmentService.FetchAllDepartmentAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the lab departments asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-lab-departments-status")]
        public async Task<ActionResult> FetchLabDepartmentsAsync([FromBody] LabDepartmentModel model, [FromHeader] LocationHeader location)
        {
            model = (LabDepartmentModel)EmptyFilter.Handler(model);
            var response = await this.laboratoryDepartmentService.ModifyLabStatus(model);
            if (response > 0)
            {
                try
                {
                    var labLogModel = new LabLogModel
                    {
                        AccountId = model.CreatedBy,
                        LabLogTypeId = (int)LabLogTypes.LabDepartment,
                        LogFrom = model.LoginRoleId > 0 ? (short)model.LoginRoleId : short.Parse(1.ToString()),
                        LogDate = DateTime.UtcNow,
                        LocationId = int.Parse(location.LocationId),
                        LogDescription = $@"Department : <b>{model.DepartmentName}</b> successfully {((bool)model.Active ? "Activated" : "Deactivated")} by {model.CreatedByName}"
                    };
                    await this.labLogService.LogAsync(labLogModel);
                }
                catch (Exception)
                {
                    // ignore
                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// Fetches the labs and package combined asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header">The header.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-combined-lab-and-package")]
        public async Task<ActionResult> FetchLabsAndPackageCombinedAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        {
            model = (RequestLaboratory)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryService.FetchAllLabs(model);
            var packageResponse = await this.laboratoryPackageService.FetchAllLabPackages(new LabPackageModel { Name = model.LabName, LocationId = (int)model.LocationId, PageIndex = model.PageIndex, PageSize = model.PageSize });

            var combinedList = new List<LabHeaderModel>();
            combinedList.AddRange(response);
            var packageResponses = packageResponse.Select(p => new LabHeaderModel
            {
                Charge = p.Amount,
                LabName = p.Name,
                LabPackageId = p.LabPackageId,
                LabHeaderId = 0
            });
            combinedList.AddRange(packageResponses);

            return this.Success(combinedList);
        }


        /// <summary>    
        /// The update lab booking Detail for updating the barcode async.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("update-barcode-for-lab")]
        public async Task<ActionResult> UpdateLabBookingDetailForBarcodeAsync([FromBody] LabSample model)

        {
            var response = await this.laboratoryService.UpdateLabBookingDetailForBarcodeAsync(model);
            return this.Success(response);
        }

        /// <summary>    
        /// The update package's lab booking Detail for updating the barcode async.
        /// </summary>
        /// <param name="request">The model.</param>
        /// <returns></returns>
        //[HttpPost]
        //[Route("update-barcode-for-packaged-lab")]
        //public async Task<ActionResult> UpdatePackageLabForBarcodeAsync([FromBody] RequestLaboratory request)

        //{
        //    request = (RequestLaboratory)EmptyFilter.Handler(request);
        //    var response = await this.laboratoryPackageService.UpdatePackageLabForBarcodeAsync(request);
        //    return this.Success(response);
        //}

        /// <summary>
        /// The update lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        //[HttpPost]
        //[Route("update-sample-received-status")]
        //public async Task<ActionResult> UpdateSampleReceivedAsync([FromBody] RequestLaboratory model, [FromHeader] LocationHeader header)
        //{
        //    model = (RequestLaboratory)EmptyFilter.Handler(model);
        //    model.LocationId = Convert.ToInt32(header.LocationId);
        //    var response = model.LabBookingPackageDetailId== null ? await this.laboratoryService.UpdateSampleReceivedStatus((int)model.LabBookingDetailId, (int)model.AccountId) : await this.laboratoryPackageService.UpdateSampleReceivedStatus((int)model.AccountId , (int)model.LabBookingPackageDetailId);

        //    try
        //    {
        //        var labLogModel = new LabLogModel
        //        {
        //            AccountId = model.AccountId,
        //            LabLogTypeId = (int)LabLogTypes.Lab_BookingDetails,
        //            LogFrom = (short)model.LoginRoleId,
        //            LogDate = DateTime.Now,
        //            LocationId = (int)model.LocationId,
        //            LogDescription =  $@"'{model.CreatedByName}' has Received Collected Samples for Lab: '{model.LabName}' of Bill number '{model.BillNumber}'."
        //        };
        //        await this.labLogService.LogAsync(labLogModel);
        //    }
        //    catch (Exception)
        //    {
        //        return null;
        //    }

        //    return this.Success(response);
        //}

        /// <summary>
        /// The update lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("update-selected-lab")]
        public async Task<ActionResult> UpdateSelectedLabAsync([FromBody] LabSample model)
        {
            model = (LabSample)EmptyFilter.Handler(model);

            var response = await this.laboratoryPackageService.UpdateSelectedLab(model);

            return this.Success(response);
        }

        /// <summary>
        /// The update lab booking async.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("update-received-status")]
        public async Task<ActionResult> UpdateSelectedLabReceivedAsync([FromBody] LabSample model)
        {
            model = (LabSample)EmptyFilter.Handler(model);

            var response = await this.laboratoryService.UpdateSelectedLabReceived(model);

            return this.Success(response);
        }


        /// <summary>
        /// To fetch list of patients.
        /// </summary>
        /// <param name="model">
        /// The patient model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Returns list of patients.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [Authorize]
        [Route("fetch-existing-labs-patients")]
        [ProducesResponseType(200, Type = typeof(List<PatientModel>))]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchExistingPatientsAsync([FromBody] PatientModel model)
        {
            var existingPatients = await this.laboratoryService.FetchExistingPatientsAsync(model);

            return this.Success(existingPatients);
        }

        /// <summary>
        /// The modify lab package async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("modify-import-package")]
        public async Task<ActionResult> ModifyImportPackageAsync([FromBody] PackageImportModel model, [FromHeader] LocationHeader header)
        {
            model = (PackageImportModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);
            var response = await this.laboratoryPackageService.ModifyImportPackage(model);
            return this.Success(response);
        }
    }
}