namespace Hims.Domain.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Hims.Shared.UserModels.Slots;
    using Shared.EntityModels;
    using Shared.UserModels;
    using Resource = Hims.Shared.UserModels.Discharge.Resource;

    using AvailabilityModel = Hims.Shared.UserModels.ProviderAvailability;

    /// <summary>
    /// The Provider Location Service interface.
    /// </summary>
    public interface IProviderLocationService
    {
        /// <summary>
        /// Fetches the new slots.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<List<TimeSlotModel>> FetchNewSlots(SlotRequest model);

        /// <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<ProviderAvailabilityModel>> FetchAsync(int providerId, int? specializtionId, bool? active, int? locationId);

        /// <summary>
        /// The fetch availabilities async.
        /// </summary>
        /// <param name="providerId">
        /// The provider id.
        /// </param>
        /// <param name="providerLocationId">
        /// 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<IEnumerable<ProviderAvailabilityModel>> FetchAvailabilitiesAsync(int providerId, int? providerLocationId, string fromDate, string toDate);

        /// <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(ProviderLocationModel model);

        /// <summary>
        /// The update async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateAsync(ProviderLocationModel 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(ChargeTypesModel model);

        /// <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>
        /// The fetch availabilities async.
        /// </summary>
        /// <param name="providerId">
        /// The provider id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<ProviderAvailabilityDatesModel>> FetchProviderAvailabilityDatesAsync(int providerId, int? locationId, int? specializationId, string? startDate, string? endDate, int? consultationTypeId);

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

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

        /// <summary>
        /// gets visit types id.
        /// </summary>
        /// <param name="providerId"></param>
        /// <param name="locationId"></param>
        /// <param name="specializationId"></param>
        /// <param name="visitTypeId"></param>
        /// <returns></returns>

        Task<IEnumerable<AvailabilityModel.AvailabilityModel>> GetVisitTypes(int? providerId, int? locationId, int? specializationId, int? visitTypeId);

        /// <summary>
        /// gets new charges
        /// </summary>
        /// <param name="providerId"></param>
        /// <param name="chargeTypeId"></param>
        /// <param name="specializationId"></param>
        /// <param name="locationId"></param>
        /// <param name="appointmentDate"></param>
        /// <param name="consultationTypeId"></param>
        /// <returns></returns>
        Task<IEnumerable<AvailabilityModel.AvailabilityModel>> GetNewChargesAsync(int? providerId, int? chargeTypeId, int? specializationId, int? locationId, string? appointmentDate, int? consultationTypeId);
        /// <summary>
        /// Fetches the new slots.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<List<MultipleDays>> FetchSlotsForMultipleDays(SlotRequest model);


        /// <summary>
        /// Fetches the new slots.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        Task<List<SessionTimings>> FetchSessionSlots(SlotRequest model);
    }
}