document.addEventListener('DOMContentLoaded', () => {
const convoForm = document.getElementById('new-conversation-form');
const messageForm = document.getElementById('message-form');
const messagesWrap = document.getElementById('chat-messages');
const realtimeBadge = document.getElementById('realtime-status');
const toastEl = document.getElementById('app-toast');
const convoId = messagesWrap ? Number(messagesWrap.dataset.conversationId) : 0;
const toast = toastEl ? new bootstrap.Toast(toastEl) : null;
const showToast = (text) => {
if (!toastEl || !toast) return;
toastEl.querySelector('.toast-body').textContent = text;
toast.show();
};
const renderMessages = (messages) => {
if (!messagesWrap) return;
messagesWrap.innerHTML = '';
messages.forEach((msg) => {
const bubble = document.createElement('div');
bubble.className = `message-bubble ${msg.direction === 'outbound' ? 'outbound' : ''}`;
bubble.innerHTML = `
${msg.body}
${msg.direction} · ${msg.status} · ${msg.created_at}
`;
messagesWrap.appendChild(bubble);
});
messagesWrap.scrollTop = messagesWrap.scrollHeight;
};
const fetchMessages = async () => {
if (!convoId) return;
const res = await fetch(`api/messages.php?conversation_id=${convoId}`);
if (!res.ok) return;
const data = await res.json();
renderMessages(data.messages || []);
};
if (convoForm) {
convoForm.addEventListener('submit', async (event) => {
event.preventDefault();
const formData = new FormData(convoForm);
const payload = {
contact_name: formData.get('contact_name'),
phone: formData.get('phone'),
channel: formData.get('channel')
};
const res = await fetch('api/conversations.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json();
if (data.success) {
window.location = `index.php?conversation_id=${data.conversation_id}`;
} else {
showToast(data.error || 'Unable to create conversation.');
}
});
}
if (messageForm) {
messageForm.addEventListener('submit', async (event) => {
event.preventDefault();
const formData = new FormData(messageForm);
const body = String(formData.get('body') || '').trim();
if (!body) return;
const res = await fetch('api/messages.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ conversation_id: convoId, body })
});
const data = await res.json();
if (data.success) {
messageForm.reset();
fetchMessages();
showToast('Message queued for delivery.');
} else {
showToast(data.error || 'Message failed.');
}
});
}
const connectWebSocket = () => {
if (!realtimeBadge || !window.WebSocket) return;
const wsUrl = `ws://${window.location.hostname}:8081`;
let ws;
try {
ws = new WebSocket(wsUrl);
} catch (e) {
realtimeBadge.textContent = 'Polling';
return;
}
ws.addEventListener('open', () => {
realtimeBadge.textContent = 'WebSocket';
});
ws.addEventListener('message', (event) => {
if (event.data === 'refresh') {
fetchMessages();
}
});
ws.addEventListener('close', () => {
realtimeBadge.textContent = 'Polling';
});
ws.addEventListener('error', () => {
realtimeBadge.textContent = 'Polling';
});
};
if (messagesWrap) {
fetchMessages();
setInterval(fetchMessages, 5000);
connectWebSocket();
}
const processBtn = document.getElementById('process-queue');
if (processBtn) {
processBtn.addEventListener('click', async () => {
processBtn.disabled = true;
const res = await fetch('api/queue_process.php', { method: 'POST' });
const data = await res.json();
showToast(`Processed ${data.processed || 0} queued messages.`);
setTimeout(() => window.location.reload(), 800);
});
}
});