const state = { token: null, username: null, }; const els = { authPanel: document.getElementById("auth-panel"), chatPanel: document.getElementById("chat-panel"), contextPanel: document.getElementById("context-panel"), loginForm: document.getElementById("login-form"), chatForm: document.getElementById("chat-form"), chatInput: document.getElementById("chat-message"), chatHistory: document.getElementById("chat-history"), messageTemplate: document.getElementById("message-template"), status: document.getElementById("status-message"), sessionUsername: document.getElementById("session-username"), logoutBtn: document.getElementById("logout-btn"), accountsList: document.getElementById("accounts-list"), beneficiariesList: document.getElementById("beneficiaries-list"), transactionsList: document.getElementById("transactions-list"), }; const api = async (path, options = {}) => { const headers = { "Content-Type": "application/json", ...options.headers, }; if (state.token) { headers.Authorization = `Bearer ${state.token}`; } const response = await fetch(path, { ...options, headers, }); const data = await response.json().catch(() => ({})); if (!response.ok) { throw new Error(data.error || "Request failed"); } return data; }; const setStatus = (message, isError = false) => { els.status.textContent = message || ""; els.status.style.color = isError ? "#ff7a18" : "#a5ffce"; }; const toggleChat = (loggedIn) => { els.authPanel.classList.toggle("hidden", loggedIn); els.chatPanel.classList.toggle("hidden", !loggedIn); els.contextPanel.classList.toggle("hidden", !loggedIn); if (!loggedIn) { els.chatHistory.innerHTML = ""; els.sessionUsername.textContent = ""; els.chatInput.value = ""; renderSnapshot({}); } }; const appendMessage = ({ sender, message, timestamp }) => { const node = els.messageTemplate.content.firstElementChild.cloneNode(true); node.classList.add(sender); node.querySelector(".sender").textContent = sender === "user" ? "You" : "Aurora"; node.querySelector(".content").textContent = message; node.querySelector("time").textContent = new Date(timestamp || Date.now()).toLocaleTimeString(); els.chatHistory.appendChild(node); els.chatHistory.scrollTop = els.chatHistory.scrollHeight; }; const renderChat = (history = []) => { els.chatHistory.innerHTML = ""; history.forEach((entry) => appendMessage(entry)); }; const formatAmount = (value) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 2, }).format(Number(value)); const renderSnapshot = (snapshot = {}) => { const accounts = snapshot.accounts || []; const beneficiaries = snapshot.beneficiaries || []; const transactions = (snapshot.transactions || []).slice(0, 10); els.accountsList.innerHTML = accounts .map( (acct) => `
  • ${acct.name}
    ${acct.id} • ${acct.type}
    ${formatAmount( acct.balance, )}
  • `, ) .join("") || "
  • No accounts available.
  • "; els.beneficiariesList.innerHTML = beneficiaries .map( (ben) => `
  • ${ben.name}
    ${ben.bank}
    ${ben.account_number}${ ben.notes ? ` • ${ben.notes}` : "" }
  • `, ) .join("") || "
  • No beneficiaries stored.
  • "; els.transactionsList.innerHTML = transactions .map( (tx) => `
  • ${tx.description}
    ${tx.account_id} • ${new Date( tx.timestamp, ).toLocaleString()}
    ${formatAmount(tx.amount)}
  • `, ) .join("") || "
  • No transactions available.
  • "; }; els.loginForm.addEventListener("submit", async (event) => { event.preventDefault(); const formData = new FormData(event.currentTarget); const payload = Object.fromEntries(formData.entries()); try { const result = await api("/api/login", { method: "POST", body: JSON.stringify(payload), headers: {}, }); state.token = result.token; state.username = result.user.username; els.sessionUsername.textContent = `Signed in as ${state.username}`; setStatus("Login successful. Start chatting with Aurora."); toggleChat(true); renderSnapshot(result.snapshot || {}); } catch (error) { setStatus(error.message, true); } }); els.chatForm.addEventListener("submit", async (event) => { event.preventDefault(); if (!state.token) { setStatus("Please login first.", true); return; } const message = els.chatInput.value.trim(); if (!message) return; const optimistic = { sender: "user", message, timestamp: new Date().toISOString(), }; appendMessage(optimistic); els.chatInput.value = ""; els.chatForm.querySelector("button").disabled = true; try { const result = await api("/api/chat", { method: "POST", body: JSON.stringify({ message }), }); renderChat(result.history); renderSnapshot(result.snapshot || {}); } catch (error) { setStatus(error.message, true); } finally { els.chatForm.querySelector("button").disabled = false; } }); els.logoutBtn.addEventListener("click", () => { state.token = null; state.username = null; setStatus("You have logged out."); toggleChat(false); }); // ensure chat area is hidden by default toggleChat(false);