// SPDX-License-Identifier: MIT OR Apache-2.0
// Author: Kan-Ru Chen
(function (global) {
    const default_avatar = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAdnJLH8AAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+kCFwQBL/9SeGgAAARVSURBVFjD7VhdaBxVFP6+O7tNmkTQKhXrD0YLa2JnN8nsbAORxgffNCpCkQrSB6HgD1hNoBYDImhLtSiK6JtFpSpaRa21rxJaMDs7u5tduyhII7RRQ60/LcGY7NzjQzbtZjLJJpM2jZDzeO65936cc+4537nAqixNGKQ0OzZ3kGJryNX+NSU8Xsimj4W5LN6RuktTumaj4J/UzBSzg1n/UmQGsGSyh+A+QFoAQAXgF8iLAEIBFMo9inwhcFEJTMsuUWNXIed8fUF9EVxqL6G+AthyxcJJtsLgYdOy98wAGLfsZwk8t8CcOBsagOCPBQLdbSZTOwGALe3tt0RV5EeQ9bVjJKOGLrfncrlfwwBMJDo36KiXI7i+9lXyjwcdi0RV5MkgcAL5lgIHpK4ohjH57+e5QuFMWA8ODX33Szwe34Ro/UMgmitADBBJgnf7vLjWgPEETStVJLHJB/+VguvsWs78My37VZJ9PjcVFCm3+o3LCq8t9wPxFPYHlIxmBbDJry85zuhyAwy8k7xKrfROEgl4PeVam1pbWxuN+sYHAMAbH/uyVCqNLcWu+m6SMzAFeJC5+Q6JxbqaIg2NDhUPUvFgpKHRicW6msLa+WpsflaDqULvQTDgedg+3yF1TRMPz+w2bJnShbObAVBhOwQDIuJdCHEhk+Yi0yJ6iXUX66TjlAB01wjx/DIO/SlETlclzukJhU/C2oWiW7Wkra3turIRfRQAIt7kB/l8/vel2K3KqvzvZpLAecKyUppGW51477quWw5z2U2dnfXXlPVjCjo9lMk4oVrd3GJ8o4BrJ2jEAPSGAbhu0tsLcqeGOgNg/UL2LKYO5iouf8a0UtsWzfc67EdAPj11huQXTBbiyZRMtzqCx6nk8UpF901kegeFGZDrSByIWykpuOmPF0ZGU9tIHJjChrMwuCNwJLDtVhG8L4LENGlQVRTbALFFNN4L2lzMZIYBfT9EzgOoA/GRadmH7mxPxedkPbadMK3UZyQ+BLBGRM5p6p5COv1zIJvRfAegVc1oOO3BaspTdJ3o3KHa3AHqQySbq3b9BOGgEKOV6e16EJ0Abq9ixydFuDVoOK+i/ZN+uhUJGPnmfTjF7GDWNM0OqVvbT5HKwMWNIDYyqDaIjAvwluFNvpTP5/+uMW5GlvCKq0AWi38B6LvDsvavEfWgEPcRuA3AzRWTUwKcpPBwWeGLpYwQjCft8/65ZEK8G35w3d+WsyAnEp0bJKpHfOl2TgEYnk3aVO9ydwwd1b0BXWQ4AsFREKYvF/riVsrWxABExi7r7xbZqATdALbMLm08GhGDb0LjKQINPvjdCugGefl/tzjn18fbqphOj4hI/8pjCdxdct1TCgC+d53XRWQPAFkB0AQiLxcz6TdmdJKi6zxPLT0iOHHFkAlOaPHuLbhOf2AdHMo6RwAcSSSTbRqwIbyRvp8vgT4W3jX6GGHs8+XaOCgjCnAKbiaPVbnE8h/vS9p4vH6MEwAAAABJRU5ErkJggg==';
    var styleCallback = function () {
        const style = document.createElement('style');
        style.textContent = `
            .pinka-comments .pinka-comment {
                border: 1px solid #ccc;
                border-radius: 5px;
                padding: 10px;
                margin: 10px 0;
                display: flex;
                flex-direction: column;
            }
            .pinka-comments .pinka-comment-author {
                display: flex;
                align-items: center;
            }
            .pinka-comments .pinka-comment-author-avatar {
                width: 40px;
                height: 40px;
                border-radius: 5px;
                margin-right: 10px;
            }
            .pinka-comments .pinka-comment-author-name-container {
                display: flex;
                flex-direction: column;
            }
            .pinka-comments .pinka-comment-author-name {
                font-weight: bold;
                text-decoration: none;
                color: black;
            }
            .pinka-comments .pinka-comment-content {
                margin-left: 50px;
            }
            .pinka-comments .pinka-load-more {
                display: block;
                margin: 10px auto;
                padding: 10px 20px;
                background-color: #007bff;
                color: #fff;
                border: none;
                cursor: pointer;
            }
            @media (prefers-color-scheme: dark) {
                .pinka-comments .pinka-comment {
                    border-color: #444;
                }
                .pinka-comments .pinka-comment-author-avatar.default-avatar {
                    filter: invert(1);
                }
                .pinka-comments .pinka-comment-author-name {
                    color: #eee;
                }
                .pinka-comments .pinka-load-more {
                    background-color: #0056b3;
                }
            }
        `;
        document.head.appendChild(style);
    };

    const enrichAuthorDetails = async function (items) {
        const options = {
            headers: {
                'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
            },
            cache: 'no-cache'
        };
        const authorIds = items.map(item => item.attributedTo);
        const uniqueAuthorIds = new Set(authorIds);
        const authorDetailsPromises = Array.from(uniqueAuthorIds).map(async (authorId) => {
            const authorResponse = await fetch(authorId, options);
            return authorResponse.json();
        });

        const authorDetails = await Promise.all(authorDetailsPromises);

        const authorDetailsMap = new Map();
        authorDetails.forEach(author => {
            authorDetailsMap.set(author.id, author);
        });

        items.forEach(item => {
            item.authorDetails = authorDetailsMap.get(item.attributedTo);
        });

        return items;
    };

    const renderOnePage = function (items) {
        const container = document.querySelector('.pinka-comments .pinka-comments-list');
        if (!container) return;

        // Render the replies
        items.forEach(function (reply) {
            const commentDiv = document.createElement('div');
            commentDiv.className = 'pinka-comment';

            const authorDiv = document.createElement('div');
            authorDiv.className = 'pinka-comment-author';

            const avatarImg = document.createElement('img');
            avatarImg.className = 'pinka-comment-author-avatar';
            avatarSrc = reply.authorDetails && reply.authorDetails.icon ? reply.authorDetails.icon.url : '';
            if (!avatarSrc) {
                avatarSrc = default_avatar;
                avatarImg.classList.add('default-avatar');
            }
            avatarImg.src = avatarSrc;
            avatarImg.alt = reply.authorDetails ? reply.authorDetails.name : 'Unknown';

            const authorNameContainer = document.createElement('div');
            authorNameContainer.className = 'pinka-comment-author-name-container';

            const authorNameSpan = document.createElement('a');
            authorNameSpan.className = 'pinka-comment-author-name';
            authorNameSpan.textContent = reply.authorDetails ? reply.authorDetails.name : 'Unknown';
            authorNameSpan.href = reply.authorDetails ? reply.authorDetails.id : '#';
            authorNameSpan.target = '_blank';

            const authorPreferredNameSpan = document.createElement('span');
            authorPreferredNameSpan.className = 'pinka-comment-author-preferred-name';
            authorPreferredNameSpan.textContent = reply.authorDetails && reply.authorDetails.preferredUsername ? `@${reply.authorDetails.preferredUsername}` : '';

            authorNameContainer.appendChild(authorNameSpan);
            authorNameContainer.appendChild(authorPreferredNameSpan);

            authorDiv.appendChild(avatarImg);
            authorDiv.appendChild(authorNameContainer);

            const contentDiv = document.createElement('div');
            contentDiv.className = 'pinka-comment-content';
            // SAFETY: Pinka is a trusted source, so we can safely set the innerHTML
            contentDiv.innerHTML = reply.content;

            commentDiv.appendChild(authorDiv);
            commentDiv.appendChild(contentDiv);

            container.appendChild(commentDiv);
        });
    };

    var renderCallback = async function (repliesPage) {
        const container = document.querySelector('.pinka-comments');
        if (!container) return;

        const comments_list = document.createElement('div');
        comments_list.className = 'pinka-comments-list';
        container.appendChild(comments_list);

        const enrichedItems = await enrichAuthorDetails(repliesPage.items || repliesPage.orderedItems);
        renderOnePage(enrichedItems);

        // Add a load more button
        const loadMoreButton = document.createElement('button');
        loadMoreButton.className = 'pinka-load-more';
        loadMoreButton.textContent = 'Load More';

        loadMoreButton.onclick = async function () {
            if (repliesPage.next) {
                const options = {
                    headers: {
                        'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
                    },
                    cache: 'no-cache'
                };
                const nextPageResponse = await fetch(repliesPage.next, options);
                const nextPage = await nextPageResponse.json();
                if (nextPage && nextPage.orderedItems) {
                    const enrichedNextPageItems = await enrichAuthorDetails(nextPage.orderedItems);
                    renderOnePage(enrichedNextPageItems);
                    repliesPage = nextPage; // Update the current page to the next page
                }
            }
        };

        container.appendChild(loadMoreButton);
    };

    global.Pinka = {
        setStyleFn: function (callback) {
            styleCallback = callback;
        },
        setRenderFn: function (callback) {
            renderCallback = callback;
        },
        href: window.location.href
    };

    document.addEventListener('DOMContentLoaded', function () {
        styleCallback();
        // Fetch the replies and call renderCallback with the replies
        fetchReplies().then(renderCallback);
    });

    async function fetchReplies() {
        const headers = {
            'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
        };
        const response = await fetch(global.Pinka.href, {
            headers
        });
        const data = await response.json();
        if (!data || !data.replies || !data.replies.id || !data.replies.totalItems || data.replies.totalItems === 0) {
            console.debug('No replies found');
            return { items: [] };
        }
        const repliesResponse = await fetch(data.replies.id, {
            headers
        });
        const replies = await repliesResponse.json();
        if (!replies || !replies.first) {
            console.debug('No replies found');
            return { items: [] };
        }
        const firstPageResponse = await fetch(replies.first, {
            headers
        });
        const firstPage = await firstPageResponse.json();
        if (!firstPage || !firstPage.orderedItems) {
            console.debug('No replies found');
            return { items: [] };
        }
        return firstPage;
    }
})(window);