'use client';
import React, { useState, useEffect, useRef } from 'react';
import { Message, Language, SUPPORTED_LANGUAGES } from '@/types';
import { ChatMessage } from './ChatMessage';
import { ChatInput } from './ChatInput';
import { LanguageSelector } from './LanguageSelector';
import { FaMicrophone, FaMicrophoneSlash, FaGlobe, FaCog } from 'react-icons/fa';
import { Card } from './shared/Card';
export function Chat() {
const [messages, setMessages] = useState<Message[]>([]);
const [language, setLanguage] = useState<Language>(SUPPORTED_LANGUAGES[0]);
const [voiceEnabled, setVoiceEnabled] = useState(true);
const [showSettings, setShowSettings] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// Load messages from localStorage
const savedMessages = localStorage.getItem('chatMessages');
if (savedMessages) {
setMessages(JSON.parse(savedMessages));
}
// Load settings from localStorage
const savedLanguage = localStorage.getItem('chatLanguage');
if (savedLanguage) {
const lang = SUPPORTED_LANGUAGES.find(
(l) => l.code === JSON.parse(savedLanguage).code
);
if (lang) setLanguage(lang);
}
const savedVoiceEnabled = localStorage.getItem('voiceEnabled');
if (savedVoiceEnabled !== null) {
setVoiceEnabled(JSON.parse(savedVoiceEnabled));
}
}, []);
useEffect(() => {
// Save messages to localStorage
localStorage.setItem('chatMessages', JSON.stringify(messages));
}, [messages]);
useEffect(() => {
// Save settings to localStorage
localStorage.setItem('chatLanguage', JSON.stringify(language));
localStorage.setItem('voiceEnabled', JSON.stringify(voiceEnabled));
}, [language, voiceEnabled]);
useEffect(() => {
// Scroll to bottom when messages change
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
const handleSendMessage = async (text: string, audioBlob?: Blob) => {
// Create user message
const userMessage: Message = {
id: Date.now().toString(),
text: text || 'Voice message',
type: 'user',
timestamp: Date.now(),
language: language.code,
};
if (audioBlob) {
// Convert blob to base64 for storage
const reader = new FileReader();
reader.onloadend = () => {
userMessage.audioUrl = reader.result as string;
setMessages((prev) => [...prev, userMessage]);
};
reader.readAsDataURL(audioBlob);
} else {
setMessages((prev) => [...prev, userMessage]);
}
try {
// Send to backend API
const response = await fetch('/api/legal/ask-legal-question', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: text,
audioBlob: audioBlob ? await audioBlob.arrayBuffer() : undefined,
language: language.code,
}),
});
const data = await response.json();
// Create bot message
const botMessage: Message = {
id: Date.now().toString(),
text: data.text,
type: 'bot',
timestamp: Date.now(),
language: language.code,
};
if (data.audioUrl) {
botMessage.audioUrl = data.audioUrl;
}
setMessages((prev) => [...prev, botMessage]);
} catch (error) {
console.error('Error sending message:', error);
// Add error message
setMessages((prev) => [
...prev,
{
id: Date.now().toString(),
text: 'Sorry, there was an error processing your request.',
type: 'bot',
timestamp: Date.now(),
language: language.code,
},
]);
}
};
return (
<div className="flex h-screen flex-col bg-gradient-to-br from-blue-50 to-indigo-50">
<div className="border-b bg-white px-6 py-4 shadow-sm">
<div className="mx-auto flex max-w-7xl items-center justify-between">
<h1 className="text-2xl font-bold text-gray-900">Legal Chat Assistant</h1>
<div className="flex items-center gap-4">
<button
onClick={() => setShowSettings(!showSettings)}
className="rounded-full p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700"
title="Settings"
>
<FaCog />
</button>
<button
onClick={() => setVoiceEnabled(!voiceEnabled)}
className={`rounded-full p-2 transition-colors ${
voiceEnabled
? 'bg-blue-100 text-blue-500 hover:bg-blue-200'
: 'bg-gray-100 text-gray-500 hover:bg-gray-200'
}`}
title={voiceEnabled ? 'Disable voice' : 'Enable voice'}
>
{voiceEnabled ? <FaMicrophone /> : <FaMicrophoneSlash />}
</button>
<div className="relative">
<LanguageSelector
currentLanguage={language}
onLanguageChange={setLanguage}
/>
</div>
</div>
</div>
</div>
{showSettings && (
<Card className="absolute right-6 top-20 z-10 w-80">
<h3 className="mb-4 text-lg font-semibold">Settings</h3>
<div className="space-y-4">
<div className="flex items-center justify-between">
<span className="text-gray-700">Voice Input/Output</span>
<button
onClick={() => setVoiceEnabled(!voiceEnabled)}
className={`relative h-6 w-11 rounded-full transition-colors ${
voiceEnabled ? 'bg-blue-500' : 'bg-gray-300'
}`}
>
<span
className={`absolute left-1 top-1 h-4 w-4 rounded-full bg-white transition-transform ${
voiceEnabled ? 'translate-x-5' : ''
}`}
/>
</button>
</div>
<div>
<label className="mb-2 block text-sm text-gray-700">Language</label>
<LanguageSelector
currentLanguage={language}
onLanguageChange={setLanguage}
/>
</div>
</div>
</Card>
)}
<div className="flex-1 overflow-y-auto px-6 py-4">
<div className="mx-auto max-w-3xl space-y-6">
{messages.length === 0 ? (
<div className="flex flex-col items-center justify-center space-y-4 py-12 text-center text-gray-500">
<FaGlobe className="h-12 w-12" />
<div>
<p className="text-lg font-medium">Welcome to Legal Chat Assistant</p>
<p className="mt-1">Ask any legal question in your preferred language</p>
</div>
</div>
) : (
messages.map((message) => (
<ChatMessage key={message.id} message={message} />
))
)}
<div ref={messagesEndRef} />
</div>
</div>
<div className="border-t bg-white px-6 py-4">
<div className="mx-auto max-w-3xl">
<ChatInput
onSendMessage={handleSendMessage}
voiceEnabled={voiceEnabled}
language={language.name}
/>
</div>
</div>
</div>
);
}