import { useState, useEffect } from "react"; import { ChatHeader } from "@/components/ChatHeader"; import { ChatMessage } from "./ChatMessage"; import { ChatInput } from "./ChatInput"; import { ChatSidebar } from "./ChatSidebar"; import { ScrollArea } from "@/components/ui/scroll-area"; import { chatService, StoredChat } from "@/services/chat"; import { useToast } from "@/hooks/use-toast"; import { getModelId } from "@/config/models"; interface Message { id: string; role: "user" | "assistant"; content: string; model?: string; attachments?: Array<{ name: string; type: string; size: number; }>; } export const ChatView = () => { const { toast } = useToast(); const [isChatSidebarCollapsed, setIsChatSidebarCollapsed] = useState(false); const [selectedModel, setSelectedModel] = useState("GPT-4o"); // Inicia com "0" - será atualizado com o chat_id real após primeira resposta da API const [currentChatId, setCurrentChatId] = useState("0"); const [systemPrompt, setSystemPrompt] = useState("Você é um assistente útil e prestativo."); const [messages, setMessages] = useState([ { id: "1", role: "assistant", content: "Olá! Sou o assistente HGTX Codex. Como posso ajudá-lo hoje?", model: "GPT-4o", }, ]); const [isLoading, setIsLoading] = useState(false); // Salva o chat no localStorage sempre que as mensagens mudam useEffect(() => { if (messages.length > 1) { // Salva apenas se houver mensagens além da inicial saveCurrentChat(); // Dispara evento customizado para a sidebar recarregar window.dispatchEvent(new Event('chatUpdated')); } }, [messages]); // Função para salvar o chat atual const saveCurrentChat = () => { try { const chatTitle = chatService.generateChatTitle( messages.find(m => m.role === 'user')?.content || 'Nova Conversa' ); const storedChat: StoredChat = { id: currentChatId, title: chatTitle, createdAt: new Date(), updatedAt: new Date(), model: selectedModel, systemPrompt: systemPrompt, messages: messages.map(msg => ({ ...msg, timestamp: new Date(), })), }; chatService.saveChat(storedChat); } catch (error) { console.error('Erro ao salvar chat:', error); } }; const handleNewChat = () => { // Reseta para "0" - novo chat sempre começa com chat_id "0" setCurrentChatId("0"); setMessages([ { id: "1", role: "assistant", content: "Olá! Sou o assistente HGTX Codex. Como posso ajudá-lo hoje?", model: selectedModel, }, ]); // Dispara evento para atualizar a sidebar window.dispatchEvent(new Event('chatUpdated')); }; const handleLoadChat = (chat: StoredChat) => { // Carrega um chat existente do histórico setCurrentChatId(chat.id); setSelectedModel(chat.model); setSystemPrompt(chat.systemPrompt); // Converte mensagens do StoredChat para Message const loadedMessages: Message[] = chat.messages.map(msg => ({ id: msg.id, role: msg.role, content: msg.content, model: msg.model, attachments: msg.attachments, })); setMessages(loadedMessages); }; const handleSendMessage = async (content: string, files?: File[]) => { // Adiciona mensagem do usuário na interface const newMessage: Message = { id: Date.now().toString(), role: "user", content, attachments: files?.map((file) => ({ name: file.name, type: file.type, size: file.size, })), }; setMessages((prev) => [...prev, newMessage]); setIsLoading(true); try { // Envia mensagem para a API // Converte o nome do modelo para o ID da API const modelId = getModelId(selectedModel); const response = await chatService.sendMessage({ chatId: currentChatId, message: content, modelId: modelId, personalidade: systemPrompt, anexos: files, }); // Adiciona resposta da IA na interface if (response.success) { // IMPORTANTE: Atualiza o chat_id com o valor retornado pela API // Isso mantém o contexto da conversa para as próximas mensagens if (response.chat_id && response.chat_id !== currentChatId) { console.log(`Chat ID atualizado: ${currentChatId} → ${response.chat_id}`); setCurrentChatId(response.chat_id); } const aiResponse: Message = { id: (Date.now() + 1).toString(), role: "assistant", content: response.response, model: selectedModel, }; setMessages((prev) => [...prev, aiResponse]); } else { throw new Error('Resposta inválida da API'); } } catch (error: any) { console.error('Erro ao enviar mensagem:', error); // Mostra toast de erro para o usuário toast({ title: "Erro ao enviar mensagem", description: error.message || "Não foi possível comunicar com a IA. Tente novamente.", variant: "destructive", }); // Adiciona mensagem de erro na interface const errorMessage: Message = { id: (Date.now() + 1).toString(), role: "assistant", content: "Desculpe, ocorreu um erro ao processar sua mensagem. Por favor, tente novamente.", model: selectedModel, }; setMessages((prev) => [...prev, errorMessage]); } finally { setIsLoading(false); } }; return (
{/* Chat Sidebar - Hidden on mobile */}
setIsChatSidebarCollapsed(!isChatSidebarCollapsed)} onNewChat={handleNewChat} onSelectChat={handleLoadChat} currentChatId={currentChatId} />
{/* Main Chat Area */}
{messages.map((message) => ( ))} {isLoading && (
)}
); };