namespace Hims.Domain.Services
{
    using Hims.Domain.Entities;
    using Hims.Shared.UserModels.Queue;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Queue = Shared.UserModels.Queue;
    /// <summary>
    /// The AccountCredential interface.
    /// </summary>
    public interface IQueueService
    {

        Task<QueueStatusModel> GetUserCubicle(int accountId);

        /// <summary>
        /// Reduces the priority asynchronous.
        /// </summary>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<int> ReducePriorityAsync(int providerId, int locationId);

        /// <summary>
        /// Gets the appointments asynchronous.
        /// </summary>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<IEnumerable<AppointmentStatusModel>> GetAppointmentsAsync(int providerId, int locationId);
        /// <summary>
        /// Gets the appointment asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<ShortAppointmentModel> GetAppointmentAsync(int appointmentId);

        /// <summary>
        /// Gets the calling cubicle identifier.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int?> GetCallingCubicleId(int appointmentId);

        /// <summary>
        /// Gets the free cubicle identifier.
        /// </summary>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<IEnumerable<QueueStatusModel>> GetFreeCubicleId(int locationId, int appointmentId);

        /// <summary>
        /// Gets the patients for queue asynchronous.
        /// </summary>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<IEnumerable<Queue.PatientModel>> GetPatientsForQueueAsync(int providerId, int locationId);

        /// <summary>
        /// Gets the patients android device tokens by provider identifier.
        /// </summary>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="locationId"></param>
        /// <returns></returns>
        Task<IEnumerable<string>> GetPatientsAndroidDeviceTokensByProviderId(int providerId, int locationId);

        /// <summary>
        /// Gets the provider identifier by appointment identifier.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> GetProviderIdByAppointmentId(int appointmentId);

        /// <summary>
        /// Gets the provider identifier by appointment identifier.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> GetProviderLocationIdByAppointmentId(int appointmentId);

        /// <summary>
        /// Gets the android device token by appointment identifier.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<IEnumerable<string>> GetAndroidDeviceTokenByAppointmentId(int appointmentId);

        /// <summary>
        /// Waits the patient asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> WaitPatientAsync(int appointmentId);

        /// <summary>
        /// Gets the doctors asynchronous.
        /// </summary>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="appointmentIds">The appointment ids.</param>
        /// <param name="isMetaInfoOnly">if set to <c>true</c> [is meta information only].</param>
        /// <returns></returns>
        Task<IEnumerable<Queue.DoctorModel>> GetDoctorsAsync(int locationId, int? providerId, List<int>? appointmentIds, bool isMetaInfoOnly);

        /// <summary>
        /// Mobiles the fetch asynchronous.
        /// </summary>
        /// <param name="patientId">The patient identifier.</param>
        /// <returns></returns>
        Task<Queue.MobileFetchModel> MobileFetchAsync(int patientId);

        /// <summary>
        /// Gets the patients asynchronous.
        /// </summary>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="providerIds"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<IEnumerable<Queue.PatientModel>> GetPatientsAsync(int locationId, List<int> providerIds, Queue.QueueReceiveModel model);

        /// <summary>
        /// Updates the expired patients asynchronous.
        /// </summary>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="providerIds">The provider ids.</param>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> UpdateExpiredPatientsAsync(int locationId, List<int> providerIds, Queue.QueueReceiveModel model);

        /// <summary>
        /// Calls the patient asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <param name="cubicleId"></param>
        /// <returns></returns>
        Task<int> CallPatientAsync(int appointmentId, int cubicleId);

        /// <summary>
        /// Checks the int asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> CheckInAsync(int appointmentId);

        /// <summary>
        /// Completes the patient asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> CompletePatientAsync(int appointmentId);

        /// <summary>
        /// Completes the patient asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> MoveToQueuePatientAsync(int appointmentId);
        /// <summary>
        /// Accepts the asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> AcceptAsync(int appointmentId);

        /// <summary>
        /// Cancels the asynchronous.
        /// </summary>
        /// <param name="appointmentId">The appointment identifier.</param>
        /// <returns></returns>
        Task<int> CancelAsync(int appointmentId);

        /// <summary>
        /// Saves the web token asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> SaveWebTokenAsync(WebTokenModel model);

        /// <summary>
        /// Gets the queue web tokens identifier.
        /// </summary>
        /// <param name="appointmentIds">The appointment ids.</param>
        /// <returns></returns>
        Task<IEnumerable<string>> GetQueueWebTokensId(List<int> appointmentIds);
    }
}