Putting 3 different on click functions into one reusable function
A lot of present code can be made reusable.

I have made the necessary changes and created a single reusable function handleEvent

// Handle next-image click on product single page
var handleEvent = function(e, currentClass, linkClass, method) {
    e.preventDefault();

    var current = $('.' + currentClass + '.first');
    var next;

    // handles click on thumbnail
    if (typeof method == "undefined") {
        next = $(this);
    } else {
        // Handles next-image and prev-image click on product single page
        // Check if thumbnail is last, if it is make first thumbnail next
        if (current.next().hasClass(linkClass)) {
            next = current.next('.' + linkClass);
        } else {
            next = $('.' + linkClass)[method]();
        }
    }

    // Grab image src from data-image attribute
    var image = next.data('image');

    $('.woocommerce-main-image')
        .find('img')
        .animate({
            opacity: 0
        }, 300, function() {
            $(this).attr('src', image);
            $(this).animate({
                opacity: 1
            }, 300);
        });

    current.removeClass('first');
    next.addClass('first');
};


Example of calling this reusable function from three different events is as follows

// Handle next-image click on product single page
$('.images').on('click', '#next-image', function(e) {
    handleEvent(e, 'thumbnail-link', 'thumbnail-link', 'first');
});

// Handle prev-image click on product single page
$('.images').on('click', '#prev-image', function(e) {
    handleEvent(e, 'thumbnails', 'thumbnail-link', 'last');
});

// Handle click on thumbnail
$('.thumbnails').on('click', '.thumbnail-link', function(e) {
    handleEvent(e, 'thumbnail-link');
});