import React, { useState, useEffect, useRef } from 'react'; import { Send, Loader2, X, History, MessageSquarePlus, AlertCircle } from 'lucide-react'; import { Link, useParams, useNavigate } from 'react-router-dom'; import { Button } from '../../components/ui/Button'; import { Message } from '../../components/chat/Message'; import { Avatar, AvatarFallback } from '../../components/ui/Avatar'; import { cn } from '../../lib/utils'; import { useAuth } from '../../contexts/AuthContext'; import { chatService } from '../../lib/chat-service'; import type { ChatMessage, ChatInstance } from '../../types/supabase'; export default function AskQuestion() { const { chatId } = useParams(); const navigate = useNavigate(); const { user } = useAuth(); const [question, setQuestion] = useState(''); const [loading, setLoading] = useState(false); const [messages, setMessages] = useState([]); const [error, setError] = useState(null); const [chat, setChat] = useState(null); const [isNewChat, setIsNewChat] = useState(false); const [hasExistingChats, setHasExistingChats] = useState(null); const [isTyping, setIsTyping] = useState(false); const messagesEndRef = useRef(null); const scrollAreaRef = useRef(null); // Check for existing chats and redirect to most recent if on base path useEffect(() => { if (!user) return; const checkExistingChats = async () => { try { const chats = await chatService.getChatInstances(user.id); const hasChats = chats.length > 0; setHasExistingChats(hasChats); // If we're on the base ask page and there are existing chats, // redirect to the most recent one if (hasChats && !chatId && !isNewChat) { const mostRecentChat = chats[0]; // Chats are already sorted by last_message_at desc navigate(`/dashboard/ask/${mostRecentChat.id}`); } } catch (err) { console.error('Error checking existing chats:', err); setHasExistingChats(false); } }; checkExistingChats(); }, [user, chatId, navigate, isNewChat]); useEffect(() => { if (!user || !chatId) return; const loadChat = async () => { try { // Don't try to load chat if we're using a temporary ID if (chatId.startsWith('temp-')) { return; } // Load chat instance const chatInstance = await chatService.getChatInstance(chatId); if (!chatInstance) { setError('Chat not found'); return; } setChat(chatInstance); // Load messages const messages = await chatService.getChatMessages(chatId); setMessages(messages); } catch (err) { setError('Failed to load chat'); console.error('Error loading chat:', err); } }; loadChat(); }, [chatId, user]); const handleNewChat = () => { setIsNewChat(true); setChat(null); setMessages([]); setError(null); // Generate a temporary ID for the new chat const tempId = 'temp-' + Date.now(); navigate(`/dashboard/ask/${tempId}`); }; const generateChatTitle = (message: string) => { // Split into words and take first 5 const words = message.split(/\s+/).slice(0, 5); // Join words and add ellipsis if we truncated const title = words.join(' '); return words.length < message.split(/\s+/).length ? `${title}...` : title; }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!question.trim() || loading || !user) return; setLoading(true); setError(null); try { let currentChatId: string; // If no chat exists or we're on the base ask page, create a new one if (!chatId || chatId === undefined) { const title = generateChatTitle(question.trim()); const newChat = await chatService.createChatInstance(user.id, title); if (!newChat) { throw new Error('Failed to create chat instance'); } currentChatId = newChat.id; setChat(newChat); setIsNewChat(false); // Update URL with the real chat ID navigate(`/dashboard/ask/${newChat.id}`, { replace: true }); } else { currentChatId = chatId; } // Show typing indicator before sending message setIsTyping(true); // Add user message and get all updated messages including the AI response const updatedMessages = await chatService.addMessage(currentChatId, question.trim(), 'user'); setMessages(updatedMessages); setQuestion(''); } catch (err) { setError('Failed to send message'); console.error('Failed to process message:', err); } finally { setLoading(false); setIsTyping(false); } }; const clearChat = async () => { if (!chatId || isNewChat) return; try { setError(null); const success = await chatService.deleteChatInstance(chatId); if (success) { // After deleting, check if there are other chats to navigate to const remainingChats = await chatService.getChatInstances(user!.id); if (remainingChats.length > 0) { navigate(`/dashboard/ask/${remainingChats[0].id}`); } else { navigate('/dashboard/ask'); } } } catch (err) { setError('Failed to clear chat'); console.error('Error clearing chat:', err); } }; // Auto-scroll when new messages arrive useEffect(() => { if (scrollAreaRef.current) { const scrollArea = scrollAreaRef.current; scrollArea.scrollTop = scrollArea.scrollHeight; } }, [messages, isTyping]); // Show loading state while checking for existing chats if (hasExistingChats === null) { return (
); } return (
{/* Header Container */}

Ask a Question

{chat && (

{chat.title}

)}
{chatId && !isNewChat && messages.length > 0 && ( )} {hasExistingChats && ( )}
{/* Main Chat Container - Added pb-20 to create space at bottom */}
{/* Messages Container */}
{error && (
{error}
)}
{!isNewChat && !chatId ? (

Welcome to StudyAI Chat

Start a new chat to begin asking questions about your study materials

Example questions you can ask:

) : messages.length === 0 ? (

Ask Your First Question

Type your question below or choose from the examples

) : ( <> {messages.map((message) => ( ))} {isTyping && (
AI
)}
)}
{/* Input Box - Keep original styling */}
setQuestion(e.target.value)} placeholder="Ask me anything..." className={cn( 'flex-1 rounded-full px-4 py-2 text-sm', 'bg-primary/5 border-primary/10', 'focus:outline-none focus:ring-2 focus:ring-primary/20', 'placeholder:text-muted-foreground' )} disabled={loading} />
); }