document.addEventListener('DOMContentLoaded', function() { const messageForm = document.getElementById('message-form'); const messageInput = document.getElementById('message-input'); const chatBox = document.getElementById('chat-box'); const typingIndicator = document.getElementById('typing-indicator'); let currentUser = ''; let lastAnimatedMessageId = null; function showTypingIndicator() { if (typingIndicator) { typingIndicator.style.display = 'block'; chatBox.scrollTop = chatBox.scrollHeight; } } function hideTypingIndicator() { if (typingIndicator) { typingIndicator.style.display = 'none'; } } function createAvatar(message) { const avatar = document.createElement('div'); avatar.classList.add('avatar'); const initial = message.user_initial || (message.username === 'AI' ? 'A' : '?'); avatar.textContent = initial; // Add a color based on the username const colors = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107', '#ff9800', '#ff5722', '#795548', '#607d8b']; const colorIndex = message.username.charCodeAt(0) % colors.length; avatar.style.backgroundColor = colors[colorIndex]; return avatar; } function renderMessage(message) { const isSent = message.username === currentUser; if (isSent || message.username === 'AI') { hideTypingIndicator(); } const messageElement = document.createElement('div'); messageElement.classList.add('message', isSent ? 'sent' : 'received'); messageElement.dataset.messageId = message.id; const avatar = createAvatar(message); messageElement.appendChild(avatar); const messageBody = document.createElement('div'); messageBody.classList.add('message-body'); if (!isSent) { const usernameElement = document.createElement('div'); usernameElement.classList.add('message-username'); usernameElement.textContent = message.username; messageBody.appendChild(usernameElement); } const messageP = document.createElement('p'); messageP.classList.add('message-text'); messageP.textContent = message.message; const messageTime = document.createElement('span'); messageTime.classList.add('message-time'); const time = new Date(message.created_at); messageTime.textContent = time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); messageBody.appendChild(messageP); messageBody.appendChild(messageTime); messageElement.appendChild(messageBody); chatBox.appendChild(messageElement); chatBox.scrollTop = chatBox.scrollHeight; } function renderMessageWithStreaming(message) { renderMessage({ ...message, message: '' }); // Render the container first const messageP = chatBox.querySelector(`[data-message-id="${message.id}"] .message-text`); if (!messageP) return; const words = message.message.split(' '); let i = 0; const interval = setInterval(() => { if (i < words.length) { messageP.textContent += (i > 0 ? ' ' : '') + words[i]; chatBox.scrollTop = chatBox.scrollHeight; i++; } else { clearInterval(interval); } }, 100); } async function fetchMessages() { try { const response = await fetch('/api/chat.php'); if (!response.ok) { if (response.status === 401) window.location.href = 'login.php'; throw new Error('Network response was not ok'); } const data = await response.json(); if (data.success) { currentUser = data.currentUser; const messages = data.messages || []; const existingMessageIds = new Set([...chatBox.querySelectorAll('.message')].map(m => m.dataset.messageId)); messages.forEach(message => { if (!existingMessageIds.has(message.id.toString())) { const isAI = message.username === 'AI'; const isNewer = message.id > lastAnimatedMessageId; if (isAI && isNewer) { lastAnimatedMessageId = message.id; renderMessageWithStreaming(message); } else { renderMessage(message); } } }); if (messages.length > 0) { const lastMessage = messages[messages.length - 1]; if (lastMessage.username !== 'AI') { hideTypingIndicator(); } } } } catch (error) { console.error('Error fetching messages:', error); hideTypingIndicator(); } } async function resetChat() { try { const response = await fetch('/api/chat.php?action=reset'); const result = await response.json(); if (result.success) { chatBox.innerHTML = ''; } else { console.error('Error resetting chat:', result.error); } } catch (error) { console.error('Error resetting chat:', error); } } if (chatBox) { fetchMessages(); setInterval(fetchMessages, 3000); if (messageForm) { messageForm.addEventListener('submit', async function(e) { e.preventDefault(); const messageText = messageInput.value.trim(); if (messageText === '/reset') { messageInput.value = ''; await resetChat(); return; } if (messageText !== '') { messageInput.value = ''; messageInput.focus(); showTypingIndicator(); // Optimistically render user's message const tempId = `temp_${new Date().getTime()}`; renderMessage({ id: tempId, username: currentUser, message: messageText, created_at: new Date().toISOString(), user_initial: currentUser.charAt(0).toUpperCase() }); const personality = document.getElementById('ai-personality').value.trim(); try { const response = await fetch('/api/chat.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: messageText, personality: personality }) }); const result = await response.json(); if (!result.success) { console.error('Error saving message:', result.error); // Optionally remove the optimistic message or show an error const failedMsg = chatBox.querySelector(`[data-message-id="${tempId}"]`); if(failedMsg) failedMsg.classList.add('error'); } // The poller will fetch the confirmed message from the server } catch (error) { console.error('Error sending message:', error); hideTypingIndicator(); const failedMsg = chatBox.querySelector(`[data-message-id="${tempId}"]`); if(failedMsg) failedMsg.classList.add('error'); } } }); } } // Security Panel Logic const vpnConnectBtn = document.getElementById('vpn-connect-btn'); const vpnStatus = document.getElementById('vpn-status'); const vpnCountrySelect = document.getElementById('vpn-country'); const antivirusScanBtn = document.getElementById('antivirus-scan-btn'); const antivirusResult = document.getElementById('antivirus-result'); let isVpnConnected = false; if (vpnConnectBtn) { vpnConnectBtn.addEventListener('click', async () => { isVpnConnected = !isVpnConnected; if (isVpnConnected) { const selectedCountry = vpnCountrySelect.value; vpnConnectBtn.textContent = 'Desconectar'; vpnConnectBtn.classList.remove('btn-primary'); vpnConnectBtn.classList.add('btn-danger'); vpnStatus.innerHTML = '

Conectando...

'; const prompt = `Simule que você está estabelecendo uma conexão VPN para o país ${selectedCountry}. Descreva o processo e, ao final, confirme a conexão segura e forneça um endereço de IP fictício para esse país.`; try { const response = await fetch('/api/chat.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: prompt, context: 'vpn' }) // Add context for the API }); const result = await response.json(); if (result.success && result.data) { vpnStatus.innerHTML = `

${result.data.replace(/\n/g, '
')}

`; } else { vpnStatus.innerHTML = '

Falha ao conectar. Tente novamente.

'; } } catch (error) { console.error('VPN connection error:', error); vpnStatus.innerHTML = '

Ocorreu um erro na simulação.

'; } } else { vpnConnectBtn.textContent = 'Conectar'; vpnConnectBtn.classList.remove('btn-danger'); vpnConnectBtn.classList.add('btn-primary'); vpnStatus.innerHTML = '

Status: Desconectado

'; } }); } if (antivirusScanBtn) { antivirusScanBtn.addEventListener('click', async () => { antivirusScanBtn.disabled = true; antivirusResult.innerHTML = '

Verificando sistema... Isso pode levar um momento.

'; const prompt = `Simule uma verificação completa de um sistema de computador em busca de vírus e malware. Descreva as etapas da verificação (ex: verificação de memória, arquivos de inicialização, registro, arquivos do sistema). Ao final, apresente um relatório com os resultados, informando se alguma ameaça foi encontrada ou se o sistema está limpo.`; try { const response = await fetch('/api/chat.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: prompt, context: 'antivirus' }) // Add context for the API }); const result = await response.json(); if (result.success && result.data) { antivirusResult.innerHTML = `

${result.data.replace(/\n/g, '
')}

`; } else { antivirusResult.innerHTML = '

A verificação falhou. Tente novamente.

'; } catch (error) { console.error('Antivirus scan error:', error); antivirusResult.innerHTML = '

Ocorreu um erro na simulação da verificação.

'; } finally { antivirusScanBtn.disabled = false; } }); } });