using PlotLine.Models;
using PlotLine.ViewModels;

namespace PlotLine.Services;

public interface IAuthService
{
    Task<RegistrationResult> RegisterAsync(RegisterViewModel model);
    Task<AuthenticationResult> LoginAsync(LoginViewModel model);
    bool HasPendingTwoFactorLogin();
    string? GetPendingTwoFactorReturnUrl();
    Task<AuthenticationResult> CompleteTwoFactorLoginAsync(TwoFactorCodeViewModel model);
    Task<AuthenticationResult> CompleteTwoFactorRecoveryLoginAsync(TwoFactorRecoveryViewModel model);
    Task LogoutAsync();
    Task<AuthenticationResult> VerifyEmailAsync(Guid token);
    Task<AuthenticationResult> ResendVerificationEmailAsync(string email);
    Task<AuthenticationResult> ForgotPasswordAsync(ForgotPasswordViewModel model);
    Task<AuthenticationResult> ResetPasswordAsync(ResetPasswordViewModel model);
    Task<AuthenticationResult> ChangePasswordAsync(ChangePasswordViewModel model);
    Task<TwoFactorSetupResult> EnableTwoFactorAsync(int userId, string secretKey, string code);
    Task<AuthenticationResult> DisableTwoFactorAsync(int userId, string currentPassword);
    Task<IReadOnlyList<string>> GenerateRecoveryCodesAsync(int userId);
}

public interface IAccountDeletionService
{
    Task<AccountDeletionResult> HardDeleteAccountAsync(int userId);
}

public interface IPasswordService
{
    string HashPassword(string password);
    bool VerifyPassword(string password, string passwordHash);
}

public interface ITwoFactorService
{
    string GenerateSecretKey();
    string GenerateQrCodeUri(string email, string secretKey);
    bool ValidateCode(string secretKey, string code);
    bool ValidateCode(string secretKey, string code, long? lastUsedTimeStep, out long matchedTimeStep);
    string? GenerateQrCodeDataUri(string qrCodeUri);
    IReadOnlyList<string> GenerateRecoveryCodes(int count);
}

public interface IEmailService
{
    Task SendVerificationEmailAsync(string email, string displayName, Guid token);
    Task SendPasswordResetEmailAsync(string email, string displayName, Guid token);
    Task SendFeatureRequestAdminReplyAsync(FeatureRequest request, string messagePreview, string link, string actorEmail);
    Task SendFeatureRequestStatusChangedAsync(FeatureRequest request, string link, string actorEmail);
    Task SendFeatureRequestUserReplyAsync(FeatureRequest request, string messagePreview, string link, string actorEmail);
}

public interface ICurrentUserService
{
    int? UserId { get; }
    string? Email { get; }
    string? DisplayName { get; }
    bool IsAuthenticated { get; }
}
