namespace Hims.Domain.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Hims.Shared.UserModels.ServiceOrder;
    using Shared.EntityModels;
    using Shared.UserModels.Laboratory;

    /// <summary>
    /// The Laboratory Service interface.
    /// </summary>
    public interface ILaboratoryService
    {
        /// <summary>
        /// The create unit async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CreateUnitAsync(LookupValueModel model);

        /// <summary>
        /// The modify lab async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> ModifyLabAsync(LabHeaderModel model);

        /// <summary>
        /// The modify lab async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> ModifyImportLabAsync(LabImportModel model);

        /// <summary>
        /// The fetch all labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LabHeaderModel>> FetchAllLabs(RequestLaboratory model);

        /// <summary>
        /// The fetch all labs async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LabHeaderModel>> FetchImportLabs(RequestLaboratory model);

        /// <summary>
        /// The fetch lab details.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LabDetailModel>> FetchLabDetails(int id);

        /// <summary>
        /// The fetch lab details.
        /// </summary>
        /// <param name="locationId"></param>
        /// <param name="labHeaderId"></param>

        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LocationLabHeaderMapModel>> FetchLabLocationCharges(int locationId, int labHeaderId);



        /// <summary>
        /// The delete lab async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="locationId"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> DeleteLabsAsync(int id, int locationId);

        /// <summary>
        /// The add patient lab booking.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="labServicesFromServiceOrder"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> AddPatientLabBooking(AddBooking model, List<InsertLabServiceHelperModel> labServicesFromServiceOrder);

        /// <summary>
        /// The fetch lab headers based on condition.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="billNumber">
        /// The bill number.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<LabBookingHeaderModel> FetchLabHeadersBasedOnCondition(int? id, string billNumber);

        /// <summary>
        /// The fetch lab booking headers.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<IEnumerable<LabBookingHeaderModel>> FetchLabBookingHeaders(RequestLaboratory model);

        /// <summary>
        /// The fetch lab booking headers.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<IEnumerable<LabBookingHeaderModel>> FetchSampleStatus(RequestLaboratory model);

        /// <summary>
        /// The fetch booking lab details.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LabBookingDetailModel>> FetchBookingLabDetails(string? id, string? status, LabBookingDetailModel model);

        /// <summary>
        /// The update booking lab detail status.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="status">
        /// The status.
        /// </param>
        /// <param>
        /// <param name="loginId">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<int> UpdateBookingLabDetailStatus(int id, string status, int loginId);

        /// <summary>
        /// The update booking lab detail status all.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="status">
        /// The status.
        /// </param>
        /// <param name="loginId">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<int> UpdateBookingLabDetailStatusAll(int id, string status, int loginId);

        /// <summary>
        /// The insert bulk patient parameter async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<int> InsertBulkPatientParameterAsync(List<LabPatientParameterModel> model);

        /// <summary>
        /// The fetch lab report main data async.
        /// </summary>
        /// <param name="labBookingDetailId">
        /// The lab Booking detail id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<LabReportMainModel> FetchLabReportMainDataAsync(int labBookingDetailId);

        /// <summary>
        /// The fetch lab result report parameter async.
        /// </summary>
        /// <param name="labBookingDetailId">
        /// The lab booking detail id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<IEnumerable<LabReportParamModel>> FetchLabResultReportParameterAsync(int labBookingDetailId);

        /// <summary>
        /// The fetch lab daily report.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<IEnumerable<LabDailyReportModel>> FetchLabDailyReport(RequestLaboratory model);

        /// <summary>
        /// The verify lab report async.
        /// </summary>
        /// <param name="labBookingDetailId">
        /// The lab booking detail id.
        /// </param>
        /// <param name="verifiedBy">
        /// The verified by.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<int> VerifyLabReportAsync(int labBookingDetailId, int verifiedBy);

        /// <summary>
        /// The fetch booking lab details with package data async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="labBookingHeader"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<LabBookingDetailModel>> FetchBookingLabDetailsWithPackageDataAsync(int id, LabBookingHeaderModel? labBookingHeader);

        /// <summary>
        /// The cancel lab booking async.
        /// </summary>
        /// <param name="bookingHeaderId">
        /// The booking header id.
        /// </param>
        /// <param name="modifiedBy">
        /// The modified by.
        /// </param>        
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CancelLabBookingAsync(int bookingHeaderId, int modifiedBy);

        /// <summary>
        /// The fetch lab daily report.
        /// </summary>
        /// <param name="labBookingPackageDetailId">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<LabHeaderModel> FetchLab(int labBookingPackageDetailId);

        /// <summary>
        /// The cancel single lab from booking.
        /// </summary>
        /// <param name="labBookingHeaderId">
        /// The lab booking header id.
        /// </param>
        /// <param name="labBookingDetailId">
        /// The lab booking detail id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<Tuple<LabBookingHeaderModel, int>> CancelSingleLabFromBooking(int labBookingHeaderId, int labBookingDetailId);

        /// <summary>
        /// The cancel single lab from booking.
        /// </summary>
        ///// <param name="labBookingDetailId">
        ///// The lab booking header id.
        ///// </param>
        ///// <param name="barcode">
        ///// The lab booking detail id.
        ///// </param>
        /// /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>

        Task<int> UpdateLabBookingDetailForBarcodeAsync(LabSample model);

        /// <summary>
        /// The update booking lab detail status.
        /// </summary>
        /// <param name="labBookingDetailId">
        /// The id.
        /// </param>
        /// <param>
        /// <param name="loginId">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        //Task<int> UpdateSampleReceivedStatus(int labBookingDetailId, int loginId);

        /// <summary>
        /// The update booking lab detail status.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<int> UpdateSelectedLabReceived(LabSample model);

        /// <summary>
        /// The update booking lab detail status.
        /// </summary>
        /// <param name="model">
        /// The model
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        Task<IEnumerable<PatientModel>> FetchExistingPatientsAsync(PatientModel model);
    }
}
