package de.effigenix.domain.usermanagement;

/**
 * Domain errors for User Management.
 * Sealed interface ensures exhaustive handling of all error types.
 */
public sealed interface UserError {

    String code();
    String message();

    record UsernameAlreadyExists(String username) implements UserError {
        @Override public String code() { return "USER_USERNAME_EXISTS"; }
        @Override public String message() { return "Username '" + username + "' already exists"; }
    }

    record EmailAlreadyExists(String email) implements UserError {
        @Override public String code() { return "USER_EMAIL_EXISTS"; }
        @Override public String message() { return "Email '" + email + "' already exists"; }
    }

    record UserNotFound(UserId userId) implements UserError {
        @Override public String code() { return "USER_NOT_FOUND"; }
        @Override public String message() { return "User with ID '" + userId.value() + "' not found"; }
    }

    record InvalidCredentials() implements UserError {
        @Override public String code() { return "USER_INVALID_CREDENTIALS"; }
        @Override public String message() { return "Invalid username or password"; }
    }

    record UserLocked(UserId userId) implements UserError {
        @Override public String code() { return "USER_LOCKED"; }
        @Override public String message() { return "User account is locked"; }
    }

    record UserInactive(UserId userId) implements UserError {
        @Override public String code() { return "USER_INACTIVE"; }
        @Override public String message() { return "User account is inactive"; }
    }

    record RoleNotFound(RoleName roleName) implements UserError {
        @Override public String code() { return "ROLE_NOT_FOUND"; }
        @Override public String message() { return "Role '" + roleName + "' not found"; }
    }

    record InvalidPassword(String reason) implements UserError {
        @Override public String code() { return "USER_INVALID_PASSWORD"; }
        @Override public String message() { return "Invalid password: " + reason; }
    }

    record Unauthorized(String message) implements UserError {
        @Override public String code() { return "UNAUTHORIZED"; }
    }

    record InvalidEmail(String email) implements UserError {
        @Override public String code() { return "USER_INVALID_EMAIL"; }
        @Override public String message() { return "Invalid email format: " + email; }
    }

    record InvalidUsername(String reason) implements UserError {
        @Override public String code() { return "USER_INVALID_USERNAME"; }
        @Override public String message() { return "Invalid username: " + reason; }
    }

    record NullPasswordHash() implements UserError {
        @Override public String code() { return "USER_NULL_PASSWORD_HASH"; }
        @Override public String message() { return "PasswordHash cannot be null"; }
    }

    record NullRole() implements UserError {
        @Override public String code() { return "USER_NULL_ROLE"; }
        @Override public String message() { return "Role cannot be null"; }
    }

    record NullPermission() implements UserError {
        @Override public String code() { return "USER_NULL_PERMISSION"; }
        @Override public String message() { return "Permission cannot be null"; }
    }

    record InvalidStatusTransition(UserStatus from, UserStatus to) implements UserError {
        @Override public String code() { return "USER_INVALID_STATUS_TRANSITION"; }
        @Override public String message() { return "Invalid status transition from " + from + " to " + to; }
    }

    record InvalidInput(String message) implements UserError {
        @Override public String code() { return "INVALID_INPUT"; }
    }

    record RepositoryFailure(String message) implements UserError {
        @Override public String code() { return "REPOSITORY_ERROR"; }
    }
}
