document.addEventListener('DOMContentLoaded', function() {
    // Change star color on hover
    changeStarColor();

    // Handle form submission
    submitRating();

    // Auto filter when the filter is changed
    var filter = document.getElementById('min_rating');
    if (filter) {
        filter.addEventListener('change', ratingFilter);
        filter.dispatchEvent(new Event('change', { cancelable: true }));
    }

    // Initial load
    loadRatings(1);

    const quill = new Quill('#comment-editor', {
        theme: 'snow'
    });

    showRemindRating();
});

/**
 * Submits the rating form when the form is submitted.
 *
 * @param {Event} e - The event object representing the form submission.
 * @return {void} This function does not return anything.
 */
function submitRating() {
    var ratingForm = document.getElementById('erbwp-rating-form');
    if (ratingForm) {
        ratingForm.addEventListener('submit', function (e) {
            e.preventDefault();

            var rating = document.querySelector('input[name="rating"]:checked');
            var name = document.querySelector('input[name="name"]');
            var email = document.querySelector('input[name="email"]');
            var replyToCommentId = document.querySelector('input[name="replyToCommentId"]');
            var comment = document.getElementById("comment-editor").childNodes[0];
            var postId = ratingForm.getAttribute('data-post-id');
            var errorMessageDiv = document.getElementById('quill-error-message');

            // Check if the Quill editor is empty (considering only whitespace or the default empty state)
            if(comment.innerHTML.trim() === '' || comment.innerHTML.trim() === '<p><br></p>') {
                errorMessageDiv.style.display = 'block'; // Show the error message
                return; // Prevent the form from submitting
            } else {
                errorMessageDiv.style.display = 'none'; // Hide the error message if the comment is not empty
            }

            if (rating || replyToCommentId.value !== '') {
                var xhr = new XMLHttpRequest();
                xhr.open('POST', erbwp_ajax.url, true);
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        var response = JSON.parse(xhr.responseText);
                        if (response.success) {
                            if(response.data.is_hidden){
                                jQuery('#extend-message').text(response.data.hidden_reason);
                            }else{
                                jQuery('#extend-message').text('');
                            }
                            jQuery('#ratingSuccessModal').modal('show');
                            // refresh the average rating of the post
                            jQuery('#erbwp-average-rating').text('Average Rating: ' + response.data.average_rating + ' - ' + response.data.ratings_count + ' Ratings');
                            loadRatings(1);
                        } else {
                            jQuery('#ratingFailModal').modal('show');
                        }
                    }
                };

                xhr.send('action=erbwp_save_rating&rating=' + rating?.value + '&email=' + email.value + '&name=' + name.value + '&comment=' + comment.innerHTML.replace(/^<p>/, "").replace(/<\/p>$/, "") + '&post_id=' + postId + '&parent_id=' + replyToCommentId.value + '&nonce=' + erbwp_ajax.nonce);
            } else {
                alert('Please select a rating level.');
            }
        });
    }
}

/**
 * Changes the color of the stars in the rating system based on mouse events.
 *
 * @return {void} This function does not return anything.
 */
function changeStarColor() {
    var stars = document.querySelectorAll('.rating label');

    stars.forEach(function (star) {
        star.addEventListener('mouseenter', function () {
            var previousSiblings = getPreviousSiblings(star);
            previousSiblings.forEach(function (sibling) {
                sibling.style.color = 'gold';
            });
            star.style.color = 'gold';

            var nextSiblings = getNextSiblings(star);
            nextSiblings.forEach(function (sibling) {
                sibling.style.color = 'gainsboro';
            });
        });

        star.addEventListener('mouseleave', function () {
            var checkedInput = document.querySelector('.rating input:checked');
            if (checkedInput) {
                var previousSiblings = getPreviousSiblings(checkedInput.nextElementSibling);
                previousSiblings.forEach(function (sibling) {
                    sibling.style.color = 'gold';
                });
                checkedInput.nextElementSibling.style.color = 'gold';

                var nextSiblings = getNextSiblings(checkedInput.nextElementSibling);
                nextSiblings.forEach(function (sibling) {
                    sibling.style.color = 'gainsboro';
                });
            } else {
                stars.forEach(function (star) {
                    star.style.color = 'gainsboro';
                });
            }
        });
    });
}

/**
 * Returns an array of all the previous siblings of the given element.
 *
 * @param {Element} element - The element whose previous siblings are to be returned.
 * @return {Element[]} An array containing all the previous siblings of the given element.
 */
function getPreviousSiblings(element) {
    var siblings = [];
    while (element = element.previousElementSibling) {
        siblings.push(element);
    }
    return siblings;
}

/**
 * Returns an array of all the next siblings of the given element.
 *
 * @param {Element} element - The element whose next siblings are to be returned.
 * @return {Element[]} An array containing all the next siblings of the given element.
 */
function getNextSiblings(element) {
    var siblings = [];
    while (element = element.nextElementSibling) {
        siblings.push(element);
    }
    return siblings;
}

// Function to load ratings
function loadRatings(page) {
    var ratingForm = document.getElementById('erbwp-rating-form');
    var postId = ratingForm?.getAttribute('data-post-id');
    jQuery.ajax({
        url: erbwp_ajax.url,
        type: 'POST',
        data: {
            action: 'load_ratings',
            nonce: erbwp_ajax.nonce,
            erbwp_page: page,
            postId: postId
        },
        success: function(response) {
            let ratingsHTML = '';
            for(let i = 0; i < response.data.reviews.length; i++) {
                let rating = response.data.reviews[i];
                ratingsHTML += '<div class="comment-item" id="rating-'+ rating.id + '">';
                ratingsHTML += '<img src="' + rating.avatarURL + '" class="avatar"/>';
                ratingsHTML += '<span class="name">' + rating.authorName + '</span> - ';
                for (let j = 1; j <= 5; j++) {
                    if (j <= rating.ratingValue) {
                        ratingsHTML += '<i class="fa fa-star" style="color: gold;"></i>';
                    } else {
                        ratingsHTML += '<i class="fa fa-star" style="color: gainsboro;"></i>';
                    }
                }
                if(rating.isHidden){
                    if(rating.isAdmin || rating.isAuthor){
                        ratingsHTML += '<button class="btn btn-success btn-sm ml-3" onclick="approveComment(' + rating.id + ',' + response.data.currentPage + ', event)">Approve</button>';
                    }
                }
                ratingsHTML += '<span class="float-right date">' + rating.date + '</span>';
                ratingsHTML += '<br>';
                if(rating.isHidden){
                    if(rating.isAdmin || rating.isAuthor){
                        ratingsHTML += rating.comment;
                    }else{
                        ratingsHTML += '<span class="text-muted">' + rating.comment + '</span>';
                    }
                }else{
                    ratingsHTML += rating.comment;
                }
                ratingsHTML += '<br>';
                ratingsHTML += '<span class="reply-to" onclick="replyTo(' + rating.id + ', event)">Reply</span>';
                ratingsHTML += rating.childCount > 0 ? '<span class="reply-to" onclick="viewReply(' + rating.id + ', event)">View Reply (' + rating.childCount + ')</span>' : '';
                ratingsHTML += '<div class="reply-container"></div>';
                ratingsHTML += '</div>';
            }

            let paginationHTML = '<nav aria-label="Page navigation ratings">';
            paginationHTML += '<ul class="pagination justify-content-center">';
            for (let i = 1; i <= response.data.pagination.totalPages; i++) {
                if (i == response.data.pagination.currentPage) {
                    paginationHTML += '<li class="page-item active"><a class="page-link" href="#" data-erbwp_page=' + i + '>' + i + '</a></li>';
                } else {
                    paginationHTML += '<li class="page-item"><a class="page-link" href="#" data-erbwp_page=' + i + '>' + i + '</a></li>';
                }
            }
            paginationHTML += '</ul>';
            paginationHTML += '</nav>';
            ratingsHTML += paginationHTML;
            jQuery('#ratings-container').html(ratingsHTML);
        }
    });
}



// Pagination link click event
jQuery(document).on('click', '.pagination a', function(e) {
    e.preventDefault();
    var page = jQuery(this).data('erbwp_page');
    loadRatings(page);
});

function replyTo(commentId, event) {
    event.preventDefault();
    var replyToCommentId = document.getElementById('erbwp-replyToCommentId');
    replyToCommentId.value = commentId;
    var comment = document.getElementById("erbwp-name");
    comment.focus();
}

function viewReply(commentId, event) {
    event.preventDefault();
    jQuery.ajax({
        url: erbwp_ajax.url,
        type: 'POST',
        data: {
            action: 'load_reply_comment',
            nonce: erbwp_ajax.nonce,
            parentId: commentId
        },
        success: function(response) {
            console.log(response);
            let ratingsHTML = '';
            for(let i = 0; i < response.data.reviews.length; i++) {
                let rating = response.data.reviews[i];
                ratingsHTML += '<div class="comment-item-reply" id="rating-'+ rating.id + '">';
                ratingsHTML += '<img src="' + rating.avatarURL + '" class="avatar"/>';
                ratingsHTML += '<span class="name">' + rating.authorName + '</span>';
                
                if(rating.isHidden){
                    if(rating.isAdmin || rating.isAuthor){
                        ratingsHTML += '<button class="btn btn-success btn-sm ml-3" onclick="approveComment(' + rating.id + ',' + response.data.currentPage + ', event)">Approve</button>';
                    }
                }
                ratingsHTML += '<span class="float-right date">' + rating.date + '</span>';
                ratingsHTML += '<br>';
                if(rating.isHidden){
                    if(rating.isAdmin || rating.isAuthor){
                        ratingsHTML += rating.comment;
                    }else{
                        ratingsHTML += '<span class="text-muted">' + rating.comment + '</span>';
                    }
                }else{
                    ratingsHTML += rating.comment;
                }
                ratingsHTML += '<br>';
                ratingsHTML += '<span class="reply-to" onclick="replyTo(' + rating.id + ', event)">Reply</span>';
                ratingsHTML += rating.childCount > 0 ? '<span class="reply-to" onclick="viewReply(' + rating.id + ', event)">View Reply (' + rating.childCount + ')</span>' : '';
                ratingsHTML += '<div class="reply-container"></div>';
                ratingsHTML += '</div>';
            }
            let parentElementId = '#rating-' + commentId;
            jQuery(parentElementId + ' .reply-container').html(ratingsHTML);
        }
    });
}

function showRemindRating() {
    var ratingForm = document.getElementById('erbwp-rating-form');
    var postId = ratingForm?.getAttribute('data-post-id');
    jQuery.ajax({
        url: erbwp_ajax.url,
        type: 'POST',
        data: {
            action: 'calculate_reading_time',
            nonce: erbwp_ajax.nonce,
            postId: postId
        },
        success: function(response) {
            if(response.isRemindRating){
                let readingTimeInMiliSeconds = parseInt(response.readingTimeInMiliSeconds);
                setTimeout(function() {
                    jQuery('#remindRating').modal('show');
                    jQuery('#remindRating').on('shown.bs.modal', function () {
                        jQuery('#erbwp-name').focus();
                    });
                }, readingTimeInMiliSeconds);
            }
        }
    });    
}

function approveComment(commentId, currentPage, event){
    event.preventDefault();
    jQuery.ajax({
        url: erbwp_ajax.url,
        type: 'POST',
        data: {
            action: 'erbwp_approve_comment', // approve in admin
            nonce: erbwp_ajax.nonce,
            commentId: commentId
        },
        success: function(response) {
            jQuery('#notifications').html('<div class="alert alert-success alert-dismissible fade show" role="alert">Comment approved successfully<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
            
            // Remove the alert after 5 seconds
            setTimeout(function() {
                jQuery('.alert').alert('close');
            }, 5000);

            loadRatings(currentPage);
        },
        error: function(xhr, status, error) {
            jQuery('#notifications').html('<div class="alert alert-success alert-dismissible fade show" role="alert">' + error + '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
            
            // Remove the alert after 5 seconds
            setTimeout(function() {
                jQuery('.alert').alert('close');
            }, 5000);
        }
    });
}
