import { useState, useEffect, useRef } from "react";
import { FaUser, FaRobot, FaPaperPlane, FaCircle, FaPlus, FaPizzaSlice, FaInfoCircle, FaTimes, FaFilePdf, FaFileWord, FaDatabase, FaGlobe, FaSun, FaMoon } from "react-icons/fa";
import { MdOutlineContentCopy, MdCheck } from "react-icons/md";
import ReactMarkdown from "react-markdown";
import "./ChatBot.css";
const BASE_URL = "https://tanmaivan-hutmind.hf.space";
const TRANSLATIONS = {
vi: {
newChat: "Trò chuyện mới",
welcomeTitle: "Tôi có thể giúp gì cho bạn?",
welcomeSubtitle: "Hãy hỏi tôi về chính sách JRG, thông tin hệ thống Pizza Hut VN hoặc về Data Analytics Team.",
knowledgeBaseBtn: "Dữ liệu thông tin",
suggestion1: "Giới thiệu về team data analytics, ban quản lý là ai?",
suggestion1Chip: "Giới thiệu Data Analytics",
suggestion2: "Kể cho tôi nghe lịch sử hình thành của Pizza Hut!",
suggestion2Chip: "Lịch sử Pizza Hut",
suggestion3: "Data Analytics Team có ai làm việc ở nước ngoài không?",
suggestion3Chip: "Data Analytics nước ngoài",
suggestion4: "Tập đoàn JRG đang quản lý thương hiệu Pizza Hut ở những nước nào?",
suggestion4Chip: "Quy mô JRG toàn cầu",
inputPlaceholder: "Gửi tin nhắn cho HutMind...",
footerDisclaimer: "HutMind có thể mắc lỗi. Vui lòng kiểm tra lại các thông tin quan trọng.",
modalTitle: "Dữ liệu tham khảo",
modalDescription: "Dưới đây là các tài liệu và nguồn dữ liệu hiện đang được HutMind sử dụng để trả lời câu hỏi của bạn:",
errorConnection: "Đã xảy ra lỗi khi kết nối với chatbot. Vui lòng thử lại sau.",
errorInit: "Lỗi khi khởi tạo lại chatbot",
copyTooltip: "Sao chép",
themeLight: "Chế độ sáng",
themeDark: "Chế độ tối",
sources: [
{ name: "Thông tin về Data Analytics Team (JRGVN)", type: "database" },
{ name: "Hướng dẫn Chính sách Bảo mật Thông tin (2024)", type: "pdf" },
{ name: "Quy định Nghỉ phép và Nghỉ bệnh (PSL)", type: "pdf" },
{ name: "Chính sách Công tác và Tiếp khách nước ngoài (2025)", type: "pdf" },
{ name: "Chính sách Bảo mật Dữ liệu PHV (2023)", type: "word" },
{ name: "Chỉ thị Ứng phó Sự cố CNTT (DRP)", type: "pdf" },
{ name: "Danh mục từ viết tắt và Thuật ngữ chuyên môn", type: "word" },
{ name: "Quy trình và Chính sách Phần mềm", type: "pdf" },
]
},
en: {
newChat: "New Chat",
welcomeTitle: "How can I help you today?",
welcomeSubtitle: "Ask me about JRG policies, Pizza Hut VN systems, or the Data Analytics Team.",
knowledgeBaseBtn: "Knowledge Base",
suggestion1: "Intro to Data Analytics Team, who's the management?",
suggestion1Chip: "Data Analytics Intro",
suggestion2: "Tell me about the history of Pizza Hut!",
suggestion2Chip: "Pizza Hut History",
suggestion3: "Does anyone in the Data Analytics Team work overseas?",
suggestion3Chip: "Overseas Data Analytics Team",
suggestion4: "Which countries does JRG manage the Pizza Hut brand in?",
suggestion4Chip: "JRG Global Scale",
inputPlaceholder: "Message HutMind...",
footerDisclaimer: "HutMind can make mistakes. Check important info.",
modalTitle: "Reference Data",
modalDescription: "Below are the documents and data sources currently being used by HutMind to answer your questions:",
errorConnection: "An error occurred connecting to the chatbot. Please try again later.",
errorInit: "Error re-initializing chatbot",
copyTooltip: "Copy",
themeLight: "Light mode",
themeDark: "Dark mode",
sources: [
{ name: "Data Analytics Team Info (JRGVN)", type: "database" },
{ name: "Info Security Policy Guidelines (2024)", type: "pdf" },
{ name: "Leave & Sick Leave Regulations (PSL)", type: "pdf" },
{ name: "Overseas Travel & Entertainment Policy (2025)", type: "pdf" },
{ name: "PHV Data Privacy Policy (2023)", type: "word" },
{ name: "IT Disaster Recovery Directive (DRP)", type: "pdf" },
{ name: "Abbreviations & Technical Terms", type: "word" },
{ name: "Software Policy & Procedure", type: "pdf" },
]
}
};
const ChatBot = () => {
const [messages, setMessages] = useState([]);
const [userInput, setUserInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [copiedIndex, setCopiedIndex] = useState(null);
const [showKnowledgeModal, setShowKnowledgeModal] = useState(false);
const [language, setLanguage] = useState(() => localStorage.getItem("hutmind-lang") || "vi");
const [theme, setTheme] = useState(() => localStorage.getItem("hutmind-theme") || "light");
const chatWindowRef = useRef(null);
const textareaRef = useRef(null);
const t = (key) => TRANSLATIONS[language][key];
// Persist settings
useEffect(() => {
localStorage.setItem("hutmind-lang", language);
}, [language]);
useEffect(() => {
localStorage.setItem("hutmind-theme", theme);
if (theme === 'dark') {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
}, [theme]);
// Auto scroll
useEffect(() => {
if (chatWindowRef.current) {
chatWindowRef.current.scrollTop = chatWindowRef.current.scrollHeight;
}
}, [messages]);
// Adjust textarea height automatically
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height = 'auto';
textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 200)}px`;
}
}, [userInput]);
const handleSend = async () => {
if (userInput.trim() === "" || isLoading) return;
setMessages((prevMessages) => [
...prevMessages,
{ sender: "user", text: userInput },
{ sender: "bot", text: "..." },
]);
setUserInput("");
setIsLoading(true);
if (textareaRef.current) {
textareaRef.current.style.height = 'auto';
}
try {
const response = await fetch(`${BASE_URL}/process_query_stream/`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ query: userInput }),
});
if (!response.ok) {
throw new Error(t("errorConnection"));
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let botResponse = "";
let isFirstChunk = true;
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
botResponse += chunk;
if (isFirstChunk) {
setMessages((prevMessages) => [
...prevMessages.filter((msg) => msg.text !== "..."),
{ sender: "bot", text: botResponse },
]);
isFirstChunk = false;
} else {
setMessages((prevMessages) => {
const newMessages = [...prevMessages];
const lastMessageIndex = newMessages.length - 1;
if (newMessages[lastMessageIndex].sender === "bot") {
newMessages[lastMessageIndex].text = botResponse;
}
return newMessages;
});
}
}
} catch (error) {
console.error("Lỗi:", error);
setMessages((prevMessages) => [
...prevMessages.filter((msg) => msg.text !== "..."),
{ sender: "bot", text: t("errorConnection") },
]);
} finally {
setIsLoading(false);
}
};
const handleNewChat = async () => {
setMessages([]);
setIsLoading(false); // Reset loading state
try {
const response = await fetch(`${BASE_URL}/newchat/`, {
method: "GET",
});
if (!response.ok) {
throw new Error(t("errorInit"));
}
const data = await response.json();
console.log(data.message);
} catch (error) {
console.error("Lỗi:", error);
}
};
const copyToClipboard = (text, index) => {
navigator.clipboard.writeText(text).then(() => {
setCopiedIndex(index);
setTimeout(() => setCopiedIndex(null), 2000);
});
};
const getSourceIcon = (type) => {
switch (type) {
case "pdf": return
{t("welcomeSubtitle")}
{t("modalDescription")}