namespace Hims.Domain.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Hims.Shared.UserModels.ProviderAvailability;
    using Shared.EntityModels;
    using Shared.UserModels;
    using Resource = Hims.Shared.UserModels.Discharge.Resource;
    using InsertModel = Shared.UserModels.ProviderLeave.InsertModel;
    using UpdateModel = Shared.UserModels.ProviderLeave.UpdateModel;

    /// <summary>
    /// The Provider Location Service interface.
    /// </summary>
    public interface IProviderAvailabilityService
    {
        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="providerId">
        /// The provider id.
        /// </param>
        /// <param name="active">
        /// The active.
        /// </param>
        /// <param name="locationId"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<ProviderLocationModel>> FetchAsync(int providerId, bool? active, int? locationId);

        /// <summary>
        /// The fetch availabilities async.
        /// </summary>
        /// <param name="model"></param>
        /// The provider id.
        /// </param>
        /// The provider location id.
        /// </param>
        /// <param name="fromDate">
        /// The from date.
        /// </param>
        /// <param name="toDate">
        /// The to date.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<IEnumerable<FilterAvailabilityViewModel>, IEnumerable< FilterVisitTypeViewModel>>> FetchAvailabilitiesAsync(FilterAvailabilityViewModel model);

        /// <summary>
        /// The fetch availabilities async.
        /// </summary>
        /// <param name="providerId">
        /// The provider id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<ProviderAvailabilityDatesModel>> FetchAvailabilityDatesAsync(int providerId,int? locationId);

        /// <summary>
        /// The find async.
        /// </summary>
        /// <param name="providerLocationId">
        /// The provider location id.
        /// </param>
        /// <param name="patientId">
        /// The patient id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<ProviderLocationModel> FindAsync(int providerLocationId, int patientId, int? locationId );

        /// <summary>
        /// The fetch tax details async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TaxModel> FetchTaxAsync();

        /// <summary>
        /// The fetch appointment times async.
        /// </summary>
        /// <param name="providerLocationId">
        /// The provider location id.
        /// </param>
        /// <param name="appointmentDate">
        /// The appointment date.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TimeSpan>> FetchAppointmentTimesAsync(int providerLocationId, DateTime appointmentDate);

        /// <summary>
        /// The add async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> AddAsync(ModifyAvailabilityModel model);

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateAsync(ModifyAvailabilityModel model);

        /// <summary>
        /// The get delete async.
        /// </summary>
        /// <param name="providerLocationId">
        /// The provider location id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> DeleteAsync(int providerLocationId);

        /// <summary>
        /// The modify status async.
        /// </summary>
        /// <param name="providerLocationId">
        /// The provider location id.
        /// </param>
        /// <param name="modifiedBy">
        /// The modified By.
        /// </param>
        /// <param name="status">
        /// The status.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> ModifyStatusAsync(int providerLocationId, int modifiedBy, bool status);

        /// <summary>
        /// The get provider availability async.
        /// </summary>
        /// <param name="providerId">
        /// The provider id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<string> FindProviderByProviderLocationId(int providerId);

        /// <summary>
        /// Fetches the visit Types asynchronous.
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<Resource.ViewModel>> FetchVisitTypesAsync();


        /// <summary>
        /// Fetches the visit type in patient asynchronous.
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<Resource.ViewModel>> FetchVisitTypeIpAsync();

        /// <summary>
        /// Fetches the charge types asynchronous.
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<Resource.ViewModel>> FetchChargeTypesAsync();

        /// <summary>
        /// Adds the operation availability asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> AddOperationAvailabilityAsync(ProviderLocationModel model);

        /// <summary>
        /// Fetches the provider operation availabilty asynchronous.
        /// </summary>
        /// <param name="providerId">The provider identifier.</param>
        /// <param name="active">The active.</param>
        /// <returns></returns>
        Task<IEnumerable<ProviderLocationModel>> FetchProviderOperationAvailabiltyAsync(int providerId, bool? active);

        /// <summary>
        /// Updates the operation availability asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> UpdateOperationAvailabilityAsync(ProviderLocationModel model);

        /// <summary>
        /// Updates the operation availability asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> AddProviderLeaveAsync(InsertModel model);

        /// <summary>
        /// Updates the operation availability asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<int> UpdateProviderLeaveAsync(UpdateModel model);

        /// <summary>
        /// The get delete async.
        /// </summary>
        /// <param name="ProviderLeaveId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CancelAsync(int? ProviderLeaveId);


        /// <summary>
        /// The get charge availability async.
        /// </summary>
        /// <param name="ProviderLeaveId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<string> FindDateByProviderLeaveId(int? ProviderLeaveId);


        /// <summary>
        /// The get delete async.
        /// </summary>
        /// <param name="ProviderAvailabilityId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CancelAvailabilityAsync(int? ProviderAvailabilityId);


        /// <summary>
        /// The get charge availability async.
        /// </summary>
        /// <param name="ProviderLeaveId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<string> FindDateByProviderAvailabilityId(int? ProviderAvailabilityId);


        /// <summary>
        /// The get delete async.
        /// </summary>
        /// <param name="ProviderLeaveId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CancelBreakAsync(int? ProviderBreakId);


        /// <summary>
        /// The get charge availability async.
        /// </summary>
        /// <param name="ProviderLeaveId">
        /// The charge id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<string> FindDateByProviderBreakId(int? ProviderBreakId);
    }
}