document.addEventListener("DOMContentLoaded", () => { const chatbotToggler = document.querySelector(".chatbot-toggler"); const chatbotContainer = document.querySelector(".chatbot-container"); const closeBtn = document.querySelector(".chatbot-header .close-btn"); const chatbox = document.querySelector(".chatbox"); const chatInput = document.querySelector(".chat-input textarea"); const sendChatBtn = document.querySelector(".chat-input span"); const headerChatbotLink = document.getElementById('header-chatbot-link'); const apiUrl = document.querySelector('meta[name="chatbot-api-url"]').getAttribute('content'); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); let userMessage; let isTyping = false; const createChatLi = (message, className) => { const chatLi = document.createElement("li"); chatLi.classList.add("chat", className); let chatContent = className === "outgoing" ? `

${message}

` : `smart_toy

${message}

`; chatLi.innerHTML = chatContent; return chatLi; }; const saveChatHistory = () => { localStorage.setItem("riwayat_chat_bkkbn", chatbox.innerHTML); }; const loadChatHistory = () => { const savedChat = localStorage.getItem("riwayat_chat_bkkbn"); if (savedChat) { chatbox.innerHTML = savedChat; chatbox.scrollTo(0, chatbox.scrollHeight); } }; loadChatHistory(); const typeText = (element, htmlString, index, speed, callback) => { if (index < htmlString.length) { if (htmlString.charAt(index) === '<') { let closingTagIndex = htmlString.indexOf('>', index); if (closingTagIndex !== -1) { index = closingTagIndex; } } element.innerHTML = htmlString.substring(0, index + 1); chatbox.scrollTo(0, chatbox.scrollHeight); setTimeout(() => { typeText(element, htmlString, index + 1, speed, callback); }, speed); } else { if (callback) callback(); } }; const handleChat = () => { if (isTyping) return; userMessage = chatInput.value.trim(); if (!userMessage) { alert("Peringatan: Pesan tidak boleh kosong. Silakan ketik pertanyaan Anda terlebih dahulu."); chatInput.focus(); return; } isTyping = true; chatInput.disabled = true; chatInput.placeholder = "Tulis pertanyaan Anda di sini..."; const oldSuggestions = document.querySelectorAll('.suggestions-container'); oldSuggestions.forEach(box => box.remove()); chatInput.value = ""; chatInput.style.height = "auto"; chatbox.appendChild(createChatLi(userMessage, "outgoing")); chatbox.scrollTo(0, chatbox.scrollHeight); saveChatHistory(); const incomingChatLi = createChatLi(' Asisten sedang mencari jawaban...', "incoming"); chatbox.appendChild(incomingChatLi); chatbox.scrollTo(0, chatbox.scrollHeight); const waktuMulai = performance.now(); fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify({ message: userMessage }) }) .then(response => response.json()) .then(data => { const messageWrapper = incomingChatLi.querySelector(".message-content") || incomingChatLi.querySelector("p"); const waktuSelesai = performance.now(); const waktuRespons = ((waktuSelesai - waktuMulai) / 1000).toFixed(2); console.log(`[TESTING] Waktu Respons TTFT: ${waktuRespons} detik`); if (data.reply) { const parsedHTML = marked.parse(data.reply); messageWrapper.innerHTML = ""; typeText(messageWrapper, parsedHTML, 0, 5, () => { if (data.suggestions && data.suggestions.length > 0) { const suggestionDiv = document.createElement("div"); suggestionDiv.classList.add("suggestions-container"); chatbox.appendChild(suggestionDiv); data.suggestions.forEach((suggestion, index) => { const cleanSuggestion = suggestion.replace(/^\d+\.\s*/, '').replace(/[*"]/g, ''); if (cleanSuggestion.trim() !== "") { const btn = document.createElement("button"); btn.classList.add("suggestion-btn", "animate-in"); btn.innerText = cleanSuggestion; setTimeout(() => { suggestionDiv.appendChild(btn); }, index * 150); btn.addEventListener("click", () => { chatInput.value = cleanSuggestion; sendChatBtn.click(); suggestionDiv.remove(); }); } }); } setTimeout(() => { chatbox.scrollTo({ top: incomingChatLi.offsetTop - 20, behavior: 'smooth' }); }, 100); saveChatHistory(); isTyping = false; chatInput.disabled = false; chatInput.focus(); }); } else { messageWrapper.textContent = data.error || "Terjadi kesalahan."; isTyping = false; chatInput.disabled = false; chatInput.placeholder = "Ketik pertanyaan Anda di sini..."; } }) .catch(error => { console.error('Error:', error); const messageWrapper = incomingChatLi.querySelector(".message-content") || incomingChatLi.querySelector("p"); messageWrapper.textContent = "Maaf, tidak dapat terhubung ke asisten. Periksa koneksi Anda."; messageWrapper.style.color = "#ef4444"; isTyping = false; chatInput.disabled = false; chatInput.placeholder = "Ketik pertanyaan Anda di sini..."; }); } const handleTextareaInput = () => { chatInput.style.height = "auto"; chatInput.style.height = `${chatInput.scrollHeight}px`; }; const openChatFromLink = (event) => { event.preventDefault(); document.body.classList.add("show-chatbot"); }; sendChatBtn.addEventListener("click", handleChat); chatInput.addEventListener("keydown", (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleChat(); } }); chatInput.addEventListener("input", handleTextareaInput); chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot")); closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot")); if (headerChatbotLink) { headerChatbotLink.addEventListener('click', openChatFromLink); } });