namespace PlotLine.Models;

public class AuthenticationResult
{
    public bool Success { get; init; }
    public string? ErrorMessage { get; init; }
    public bool RequiresTwoFactor { get; init; }

    public static AuthenticationResult Succeeded() => new() { Success = true };

    public static AuthenticationResult Failed(string errorMessage) => new() { ErrorMessage = errorMessage };

    public static AuthenticationResult TwoFactorRequired() => new() { RequiresTwoFactor = true };
}

public sealed class RegistrationResult : AuthenticationResult
{
    public int? UserID { get; init; }

    public static RegistrationResult Succeeded(int userId) => new() { Success = true, UserID = userId };

    public new static RegistrationResult Failed(string errorMessage) => new() { ErrorMessage = errorMessage };
}

public sealed class TwoFactorSetupResult : AuthenticationResult
{
    public IReadOnlyList<string> RecoveryCodes { get; init; } = Array.Empty<string>();

    public static TwoFactorSetupResult Succeeded(IReadOnlyList<string> recoveryCodes)
        => new() { Success = true, RecoveryCodes = recoveryCodes };

    public new static TwoFactorSetupResult Failed(string errorMessage) => new() { ErrorMessage = errorMessage };
}

public sealed class AccountDeletionResult
{
    public bool Succeeded { get; init; }
    public bool NotFound { get; init; }
    public bool BlockedByPaidSubscription { get; init; }
    public string Message { get; init; } = string.Empty;
    public int DeletedProjectCount { get; init; }
    public int DeletedFileCount { get; init; }
    public int MissingFileCount { get; init; }
    public int FailedFileCount { get; init; }

    public static AccountDeletionResult Success(int deletedProjectCount, int deletedFileCount, int missingFileCount, int failedFileCount) => new()
    {
        Succeeded = true,
        Message = failedFileCount > 0
            ? "Your account was deleted, but some uploaded files could not be removed automatically."
            : "Your account was deleted.",
        DeletedProjectCount = deletedProjectCount,
        DeletedFileCount = deletedFileCount,
        MissingFileCount = missingFileCount,
        FailedFileCount = failedFileCount
    };

    public static AccountDeletionResult MissingUser() => new()
    {
        NotFound = true,
        Message = "The account could not be found."
    };

    public static AccountDeletionResult PaidSubscriptionBlocked() => new()
    {
        BlockedByPaidSubscription = true,
        Message = "This account cannot be deleted while a paid subscription or billing issue is active."
    };

    public static AccountDeletionResult Failure(string message) => new()
    {
        Message = message
    };
}
