namespace Hims.Domain.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Shared.EntityModels;
    using Shared.Library;
    using Shared.Library.Enums;

    using Hims.Shared.UserModels.Filters;
    using Menu = Hims.Shared.UserModels.Menu;
    using Hims.Domain.Entities;
    using Hims.Shared.UserModels.Common;

    /// <summary>
    /// The AccountService interface.
    /// </summary>
    public interface IAccountService
    {
        Task<bool> GetIsNurse(IdRequest model);

        Task<IEnumerable<string>> GetMenuButtonCodesAsync(int roleId);

        /// <summary>
        /// Updates the last login date asynchronous.
        /// </summary>
        /// <param name="accountId">The account identifier.</param>
        /// <returns></returns>
        Task<int> UpdateLastLoginDateAsync(int accountId);

        /// <summary>
        /// Gets the default menu asynchronous.
        /// </summary>
        /// <param name="menuId">The menu identifier.</param>
        /// <returns></returns>
        Task<Menu.ViewModel> GetDefaultMenuAsync(int? menuId);

        /// <summary>
        /// Fetches the menu asynchronous.
        /// </summary>
        /// <param name="accountId">The account identifier.</param>
        /// <param name="isFullAccess">if set to <c>true</c> [is full access].</param>
        /// <returns></returns>
        Task<IEnumerable<Menu.ViewModel>> FetchMenuAsync(int accountId, bool isFullAccess);

        /// <summary>
        /// Determines whether [is menu full access asynchronous] [the specified role identifier].
        /// </summary>
        /// <param name="roleId">The role identifier.</param>
        /// <returns></returns>
        Task<Menu.MenuAccessModel> IsMenuFullAccessAsync(int roleId);

        /// <summary>
        /// Gets all roles asynchronous.
        /// </summary>
        /// <returns></returns>
        Task<List<int>> GetAllRolesAsync();

        /// <summary>
        /// Gets all roles asynchronous.
        /// </summary>
        /// <returns></returns>
        Task<Role> GetPatientRolesAsync();

        /// <summary>
        /// The validate async.
        /// </summary>
        /// <param name="userName">
        /// The user name.
        /// </param>
        /// <param name="password">
        /// The password.
        /// </param>
        /// <param name="accountTypes">
        /// The account Types.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<UserAccountStatus, int>> ValidateAsync(string userName, string password);
        /// <summary>
        /// The validate async.
        /// </summary>
        /// <param name="email">
        /// The user name.
        /// </param>
        /// <param name="accountTypes">
        /// The password.
        /// </param>
        /// <param name="accountId">
        /// The account Types.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<UserAccountStatus, AccountModel>> ValidatePatientAsync(string email, IEnumerable<AccountType> accountTypes, int? accountId);
        /// <summary>
        /// The validate async.
        /// </summary>
        /// <param name="mobile">
        /// The mobile.
        /// </param>
        /// <param name="countryId">
        /// The country id.
        /// </param>
        /// <param name="accountTypes">
        /// The account Types.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<UserAccountStatus, AccountModel>> ValidateAsync(string mobile, int countryId, IEnumerable<AccountType> accountTypes);

        /// <summary>
        /// The validate async.
        /// </summary>
        /// <param name="mobile">
        /// The mobile.
        /// </param>
        /// <param name="countryId">
        /// The country id.
        /// </param>
        /// <param name="accountTypes">
        /// The account Types.
        /// </param>
        ///  /// <param name="accountId">
        /// The account Types.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<UserAccountStatus, AccountModel>> ValidatePatientAsync(string mobile, int countryId, IEnumerable<AccountType> accountTypes, int? accountId);
        /// <summary>
        /// The validate async.
        /// </summary>
        /// <param name="email">
        /// The email.
        /// </param>
        /// <param name="accountTypes">
        /// The account Types.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Tuple<UserAccountStatus, AccountModel>> ValidateAsync(string email, IEnumerable<AccountType> accountTypes);

        /// <summary>
        /// The get async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<UserAccount> FindAsync(int accountId);

        /// <summary>
        /// Finds the by location identifier asynchronous.
        /// </summary>
        /// <param name="accountId">The account identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <returns></returns>
        Task<UserAccount> FindByLocationIdAsync(int accountId, int locationId);

        /// <summary> The find account id async.</summary>
        /// <param name="referenceIds"> The reference ids.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IEnumerable<int>> FindAccountIdAsync(string referenceIds);

        /// <summary>
        /// The get role async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<RoleModel> GetRoleAsync(int accountId);

        /// <summary>
        /// The update login successful async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task UpdateLoginSuccessfulAsync(int accountId);

        /// <summary>
        /// The update failed login attempts async.
        /// </summary>
        /// <param name="email">
        /// The email.
        /// </param>
        /// <param name="mobile">
        /// The mobile.
        /// </param>
        /// <param name="countryId">
        /// The country id.
        /// </param>
        /// <param name="failedLoginAttempts">
        /// The failed login attempts.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task UpdateFailedLoginAttemptsAsync(string email, string mobile, int countryId, short failedLoginAttempts);

        /// <summary>
        /// The update agreement status async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateAgreementStatusAsync(int accountId);

        /// <summary>
        /// Find Guid
        /// </summary>
        /// <param name="referenceId">
        /// The reference id.
        /// </param>
        /// <param name="role">
        /// The role.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Guid> FindGuidAsync(int referenceId, Roles role);

        /// <summary>
        /// The find guid async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<Guid> FindGuidAsync(int accountId);

        /// <summary>
        /// Find Guid
        /// </summary>
        /// <param name="umrNumber">
        /// The umrNumber.
        /// </param>
        /// <param name="role">
        /// The role.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<AccountModel> FindGuidAsync(string umrNumber, Roles role);

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<AccountModel>> FetchAsync(UserFilterModel model);

        /// <summary>
        /// The find async.
        /// </summary>
        /// <param name="userId">
        /// The user id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<AccountModel> FindUserAsync(int userId);

        /// <summary>
        /// The modify status async.
        /// </summary>
        /// <param name="accountId">
        /// The account 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 accountId, int modifiedBy, bool status);

        /// <summary>
        /// The locked status async.
        /// </summary>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <param name="modifiedBy">
        /// The modified by.
        /// </param>
        /// <param name="status">
        /// The status.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> LockedStatusAsync(int accountId, int modifiedBy, bool status);

        /// <summary>
        /// The insert login async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> InsertLoginAsync(LoginModel model);

        /// <summary>
        /// Gets the account detail asynchronous.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="roles">The roles.</param>
        /// <returns></returns>
        Task<AccountModel> GetAccountDetailAsync(string userName, string roles);
        Task<IEnumerable<AccountModel>> GetPatientAccountDetailListAsync(string mobile, string roles, string userName);
        /// <summary>
        /// Gets the account detail asynchronous.
        /// </summary>
        /// <param name="mobile">the mobile.</param>
        /// <param name="roles">the mobile.</param>
        /// <param name="userName">the mobile.</param>

        /// <returns></returns>
        Task<IEnumerable<AccountModel>> GetAccountDetailListAsync(string mobile, string roles, string userName);

        /// <summary>
        /// The get account detail async.
        /// </summary>
        /// <param name="mobile"></param>
        /// The user name.
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<AccountModel> FindPatientByMobileAsync(string mobile);

        /// <summary>
        /// Modifies the accounts location.
        /// </summary>
        /// <param name="locationIds">The location ids.</param>
        /// <param name="accountId">The account identifier.</param>
        /// <returns></returns>
        Task<int> ModifyAccountsLocation(int[] locationIds, int accountId);
        Task<int> GetReferenceAsync(int accountId);

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<PatientModel>> FetchCallerUserDetailsAsync(IdRequest model);

    }
}