/*
CommentSystem v1.0.0 by CloudArcade
*/
class CommentSystem {
	constructor(gameId, config = {}) {
		this.gameId = gameId;
		this.commentOffset = 0;
		this.alertMsgTooshort = 'Your comment is too short. Please enter at least {{min}} characters.';
		this.config = {
			commentsPerLoad: config.commentsPerLoad || 5,  // Default to showing 5 comments
			maxReplies: config.maxReplies || 10,  // Default to showing 10 replies per comment
			minChars: config.minChars || 3,
			dateFormat: config.dateFormat || 'timeAgo' // timeAgo, ISO
		};
		this.init();
	}

	init() {
		this.loadComments();
		this.setupCommentPostForm();
		this.alertMsgTooshort = this.alertMsgTooshort.replace('{{min}}', this.config.minChars);
		document.getElementById('tpl-btn-load-more-comments').addEventListener('click', () => this.loadMoreComments());
		document.getElementById('tpl-comment-section').addEventListener('click', (event) => {
			let targetElement = event.target;
			while (targetElement != null) {
				if (targetElement.matches('.tpl-btn-show-replies')) {
					const commentId = targetElement.getAttribute('data-id');
					this.loadReplies(commentId);
					return;
				} else if (targetElement.matches('.tpl-btn-hide-replies')) {
					const commentId = targetElement.getAttribute('data-id');
					this.hideReplies(commentId);
					return;
				} else if (targetElement.matches('.tpl-comment-reply')) {
					event.preventDefault();
					const closestElement = targetElement.closest('.tpl-user-comment');
					const commentId = closestElement.getAttribute('data-id');
					this.renderReplyForm(commentId);
					return;
				}
				targetElement = targetElement.parentElement;
			}
		});
	}

	getConvertedDate(dateString, serverDate) {
		const date = new Date(dateString); // Parse the date string to a Date object
		const now = new Date(serverDate); // Current server date and time
		if (this.config.dateFormat === 'ISO') {
			const year = date.getFullYear();
			const month = String(date.getMonth() + 1).padStart(2, '0');
			const day = String(date.getDate()).padStart(2, '0');
			return `${year}-${month}-${day}`;
		} else if (this.config.dateFormat === 'timeAgo') {
			const diffInSeconds = Math.floor((now - date) / 1000);
			const years = Math.floor(diffInSeconds / (3600 * 24 * 365));
			const months = Math.floor(diffInSeconds / (3600 * 24 * 30));
			const days = Math.floor(diffInSeconds / (3600 * 24));
			const hours = Math.floor(diffInSeconds / 3600);
			const minutes = Math.floor(diffInSeconds / 60);
			if (years > 0) {
				return `${years} ${years === 1 ? 'year' : 'years'} ago`;
			} else if (months > 0) {
				return `${months} ${months === 1 ? 'month' : 'months'} ago`;
			} else if (days > 0) {
				return `${days} ${days === 1 ? 'day' : 'days'} ago`;
			} else if (hours > 0) {
				return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;
			} else if (minutes > 0) {
				return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;
			} else {
				return "Just now";
			}
		} else {
			throw new Error('Invalid config value');
		}
	}

	renderReplyForm(commentId) {
		const existingReplyForm = document.querySelector('#tpl-comment-list .tpl-reply-form');
		if (existingReplyForm) existingReplyForm.remove();
		const commentElem = document.querySelector(`.tpl-user-comment[data-id="${commentId}"]`);
		const replyFormTemplate = document.querySelector('#tpl-comment-template .tpl-reply-form').cloneNode(true);
		const sendReplyBtn = replyFormTemplate.querySelector('.tpl-btn-send-reply');
		sendReplyBtn.setAttribute('data-id', commentId);
		replyFormTemplate.querySelector('.tpl-btn-send-reply').addEventListener('click', (e) => {
			e.preventDefault();
			const content = replyFormTemplate.querySelector('.tpl-reply-input').value;
			this.postComment(content, commentId);
			replyFormTemplate.remove();
		});
		const cancelReplyBtn = replyFormTemplate.querySelector('.tpl-btn-cancel-reply');
		if(cancelReplyBtn){
			cancelReplyBtn.addEventListener('click', (e) => {
				e.preventDefault();
				replyFormTemplate.remove();
			});
		}
		commentElem.querySelector('.tpl-reply-form-wrapper').appendChild(replyFormTemplate);
	}

	loadReplies(commentId, forceLoad = false) {
		const parentCommentElem = document.querySelector(`.tpl-user-comment[data-id="${commentId}"]`);
		const showRepliesBtn = parentCommentElem.querySelector('.tpl-btn-show-replies');
		const hideRepliesBtn = parentCommentElem.querySelector('.tpl-btn-hide-replies');
		const commentChildren = parentCommentElem.querySelector('.tpl-comment-children');
		if (showRepliesBtn) showRepliesBtn.style.display = 'none';
		const repliesHTML = commentChildren.innerHTML;
		if(repliesHTML && repliesHTML.trim() !== '' && !forceLoad){
			commentChildren.style.display = 'block';
			if (hideRepliesBtn) hideRepliesBtn.style.display = 'block';
		} else {
			fetch('/includes/comment.php', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded',
				},
				body: `load_replies=true&amount=${this.config.maxReplies}&game_id=${this.gameId}&parent_id=${commentId}`
			})
			.then(response => {
				if (hideRepliesBtn) hideRepliesBtn.style.display = 'block';
				return response.json();
			})
			.then(replies => {
				if (replies && replies.length > 0) {
					const transformedReplies = this.transformData(replies);
					const childrenHtml = this.renderCommentsRecursive(transformedReplies, true);
					commentChildren.innerHTML = childrenHtml;
				}
			})
			.catch(error => {
				console.error('Failed to load replies:', error);
			});
		}
	}

	hideReplies(commentId) {
		const parentCommentElem = document.querySelector(`.tpl-user-comment[data-id="${commentId}"]`);
		const hideRepliesBtn = parentCommentElem.querySelector('.tpl-btn-hide-replies');
		const commentChildren = parentCommentElem.querySelector('.tpl-comment-children');
		const showRepliesBtn = parentCommentElem.querySelector('.tpl-btn-show-replies');
		if (hideRepliesBtn) {
			hideRepliesBtn.style.display = 'none';
		}
		if (commentChildren) {
			commentChildren.style.display = 'none';
		}
		if (showRepliesBtn) {
			showRepliesBtn.style.display = 'block';
		}
	}

	setupCommentPostForm() {
		const tooShortElem = document.querySelector('#tpl-comment-form .tpl-alert-tooshort');
		if (tooShortElem) {
			this.alertMsgTooshort = tooShortElem.innerHTML;
			tooShortElem.parentNode.removeChild(tooShortElem);
		}
		const postCommentBtn = document.querySelector('#tpl-comment-form .tpl-post-comment-btn');
		const commentInput = document.querySelector('#tpl-comment-form .tpl-comment-input');
		if(postCommentBtn){
			postCommentBtn.addEventListener('click', () => {
				const commentContent = commentInput.value;
				if (commentContent) {
					this.postComment(commentContent);
					commentInput.value = '';  // Clear the textarea
				}
			});
		}
	}

	postComment(content, parent = null) {
		if (content.length < this.config.minChars) {
			alert(this.alertMsgTooshort);
			return;
		}
		const requestData = {
			'send_comment': true,
			'game_id': this.gameId,
			'parent': parent,
			'content': content
		};
		const formData = new URLSearchParams(requestData);
		fetch('/includes/comment.php', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			body: formData
		})
		.then(response => response.text())
		.then(response => {
			console.log(response);
			if (response === 'success') {
				if (parent !== null) {
					// Is reply
					this.loadReplies(parent, true);
				} else {
					// Root comment
					this.loadComments();
				}
			} else {
				console.log('fail');
			}
		})
		.catch(error => {
			console.error('Failed to post comment:', error);
		});
	}

	loadComments(isLoadMore = false) {
		const loadMoreButton = document.getElementById('tpl-btn-load-more-comments');
		if (loadMoreButton) {
			loadMoreButton.style.display = 'none';
		}
		if (!isLoadMore) {
			// Reset offset
			this.commentOffset = 0;
		}
		const requestData = {
			'load_root_comments': true,
			'game_id': encodeURIComponent(this.gameId),
			'offset': encodeURIComponent(this.commentOffset),
			'amount': encodeURIComponent(this.config.commentsPerLoad)
		};
		const formData = new URLSearchParams(requestData);
		fetch('/includes/comment.php', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			body: formData
		})
		.then(response => response.json())
		.then(comments => {
			if (comments && comments.length > 0) {
				const transformedComments = this.transformData(comments);
				if (isLoadMore) {
					this.renderComments(transformedComments, true);
					this.commentOffset += comments.length; // Update the offset
				} else {
					this.renderComments(transformedComments);
					this.commentOffset = comments.length;
				}
			}
			if (comments.length < this.config.commentsPerLoad || comments.length === 0) {
				if (loadMoreButton) {
					loadMoreButton.remove();
				}
			} else {
				if (loadMoreButton) {
					loadMoreButton.style.display = 'block';
				}
			}
		})
		.catch(error => {
			console.error('Failed to load comments:', error);
		});
	}
	
	loadMoreComments() {
		this.loadComments(true);
	}

	transformData(array) {
		return array.map(item => {
			return {
				id: Number(item.id),
				parent_id: item.parent_id,
				created: item.created_date,
				content: item.comment,
				has_replies: item.has_replies,
				server_date: item.server_date,
				fullname: item.sender_username || 'Anonymous',
				profile_picture_url: item.avatar
			};
		});
	}

	generateCommentHtmlFromTemplate(comment, isChildren) {
		const template = document.querySelector("#tpl-comment-template .tpl-user-comment").cloneNode(true);
		template.setAttribute("data-id", comment.id);
		const elementsWithDataId = template.querySelectorAll("[data-id]");
		elementsWithDataId.forEach(element => element.setAttribute("data-id", comment.id));
		const authorElement = template.querySelector(".tpl-comment-author");
		if (authorElement) authorElement.textContent = comment.fullname;
		const timestampElement = template.querySelector(".tpl-comment-timestamp");
		if (timestampElement) timestampElement.textContent = this.getConvertedDate(comment.created, comment.server_date);
		const textElement = template.querySelector(".tpl-comment-text");
		if (textElement) textElement.textContent = comment.content;
		const avatarElement = template.querySelector("img.tpl-user-comment-avatar");
		if (avatarElement) avatarElement.setAttribute("src", comment.profile_picture_url);
		if (isChildren) {
			const replyElement = template.querySelector(".tpl-comment-reply");
			const replyFormWrapperElement = template.querySelector(".tpl-reply-form-wrapper");
			if (replyElement) replyElement.remove();
			if (replyFormWrapperElement) replyFormWrapperElement.remove();
		}
		return template;
	}

	renderCommentsRecursive(data, isChildren = false) {
		let html = "";
		data.forEach((comment) => {
			const commentHtml = this.generateCommentHtmlFromTemplate(comment, isChildren);
			const showRepliesBtn = commentHtml.querySelector('.tpl-btn-show-replies');
			const hideRepliesBtn = commentHtml.querySelector('.tpl-btn-hide-replies');
			if (comment.has_replies) {
				if (showRepliesBtn) showRepliesBtn.style.display = 'block';
				if (hideRepliesBtn) hideRepliesBtn.style.display = 'none';
			} else {
				if (showRepliesBtn) showRepliesBtn.remove();
				if (hideRepliesBtn) hideRepliesBtn.remove();
			}
			html += commentHtml.outerHTML;
		});
		return html;
	}

	renderComments(data, isLoadMore = false) {
		const html = this.renderCommentsRecursive(data);
		const commentList = document.querySelector('#tpl-comment-list');
		if (isLoadMore) {
			commentList.insertAdjacentHTML('beforeend', html);
		} else {
			commentList.innerHTML = html;
		}
	}
}