import { useState, useRef, useEffect, useCallback } from "react"; import { ChatMessages, ChatMessage } from "./public-chat/ChatMessages"; import { ChatInputBar } from "./chatbot/ChatInputBar"; import { ChatHistoryModal } from "./public-chat/ChatHistoryModal"; import { loadChatList, loadChat, sendPublicChatMessage, ChatListItem, PublicChatMessage, } from "../../services/publicChatService"; import { usePageTracking } from "../../hooks/usePageTracking"; import { toPersianDigits } from "../../utils/persianNumberUtils"; import chatbotAvatarIcon from "../../assets/chatbot-bot-avatar.png"; export function PublicChatPage() { usePageTracking("چت عمومی"); const [messages, setMessages] = useState([]); const [showChatHistory, setShowChatHistory] = useState(false); const [historyItems, setHistoryItems] = useState([]); const [currentChatWorkflowID, setCurrentChatWorkflowID] = useState(""); const [isLoading, setIsLoading] = useState(false); const [isSending, setIsSending] = useState(false); const [shouldAutoScroll, setShouldAutoScroll] = useState(true); const messagesContainerRef = useRef(null); const messagesEndRef = useRef(null); const isNearBottom = () => { const container = messagesContainerRef.current; if (!container) return true; return ( container.scrollHeight - container.scrollTop - container.clientHeight < 100 ); }; const scrollToBottom = (smooth = true) => { messagesEndRef.current?.scrollIntoView({ behavior: smooth ? "smooth" : "auto", block: "end", }); }; useEffect(() => { if (shouldAutoScroll) { scrollToBottom(); } }, [messages, shouldAutoScroll]); useEffect(() => { const container = messagesContainerRef.current; if (!container) return; const handleScroll = () => { setShouldAutoScroll(isNearBottom()); }; container.addEventListener("scroll", handleScroll, { passive: true }); return () => container.removeEventListener("scroll", handleScroll); }, []); const convertPublicChatMessagesToChatMessages = ( publicMessages: PublicChatMessage[], ): ChatMessage[] => { const converted: ChatMessage[] = []; publicMessages.forEach((msg) => { if (msg.question) { converted.push({ id: crypto.randomUUID(), type: "user", content: msg.question, timestamp: toPersianDigits(msg.datetime1), }); } if (msg.answer) { converted.push({ id: crypto.randomUUID(), type: "other", content: msg.answer, author: "ربات", timestamp: toPersianDigits(msg.datetime1), }); } }); return converted; }; const handleSelectChat = async (chatId: string) => { setShowChatHistory(false); setIsLoading(true); setCurrentChatWorkflowID(chatId); const result = await loadChat(chatId); if (result.success) { const convertedMessages = convertPublicChatMessagesToChatMessages(result.data); setMessages(convertedMessages); requestAnimationFrame(() => { requestAnimationFrame(() => { scrollToBottom(false); }); }); } else { console.error("Failed to load chat:", result.message); alert("خطا در بارگذاری چت"); } setIsLoading(false); }; const handleSendMessage = async (message: string) => { const trimmedText = message.trim(); if (!trimmedText || isSending) return; const userMessage: ChatMessage = { id: crypto.randomUUID(), type: "user", content: trimmedText, timestamp: new Date().toLocaleTimeString("fa-IR", { hour: "2-digit", minute: "2-digit", }), }; const loadingMessageId = crypto.randomUUID(); const loadingMessage: ChatMessage = { id: loadingMessageId, type: "loading", content: "", author: "ربات", timestamp: "", }; setShouldAutoScroll(true); setMessages((prev) => [...prev, userMessage, loadingMessage]); setIsSending(true); try { const result = await sendPublicChatMessage(trimmedText, currentChatWorkflowID); setMessages((prev) => prev.filter((msg) => msg.id !== loadingMessageId)); if (result.success && result.answer) { if (result.newChatlistWorkflowID) { setCurrentChatWorkflowID(result.newChatlistWorkflowID); } const botMessage: ChatMessage = { id: crypto.randomUUID(), type: "other", content: result.answer, author: "ربات", timestamp: new Date().toLocaleTimeString("fa-IR", { hour: "2-digit", minute: "2-digit", }), isTyping: true, }; setMessages((prev) => [...prev, botMessage]); } else { alert(result.message || "خطا در ارسال پیام"); } } catch (error) { setMessages((prev) => prev.filter((msg) => msg.id !== loadingMessageId)); alert("خطا در ارسال پیام"); } finally { setIsSending(false); } }; const handleHistoryClick = useCallback(async () => { setShowChatHistory(true); const result = await loadChatList(); if (result.success) { setHistoryItems(result.data); } else { console.error("Failed to load chat list:", result.message); alert(result.message || "خطا در بارگذاری تاریخچه"); } }, []); useEffect(() => { const onHistoryRequest = () => { void handleHistoryClick(); }; window.addEventListener("public-chat:history", onHistoryRequest); return () => window.removeEventListener("public-chat:history", onHistoryRequest); }, [handleHistoryClick]); return (
{isLoading ? (

در حال بارگذاری...

) : messages.length === 0 ? (
چت‌بات

با ربات همدست چت کن!

سوالاتت رو بپرس و جواب بگیر

) : (
{ if (shouldAutoScroll) { scrollToBottom(false); } }} />
)}
setShowChatHistory(false)} historyItems={historyItems.map((item) => ({ id: item.chatlist_workflowID, title: item.title || "چت عمومی", date: toPersianDigits(item.datetime1), lastMessage: "", }))} onSelectChat={handleSelectChat} />
); }