import { initializeChat as serviceInitializeChat, sendMessage as serviceSendMessage, sendOrder, getProducts } from './service.js';
let userName = '';
let userTable = null;
let products = [];
let cart = [];
let chatHistory = [
{ role: "system", content: "¡Hola! Soy tu asistente en Biergarten Klein. ¿Te gustaría una recomendación de nuestras cervezas artesanales?" }
];
// --- Elementos del DOM ---
const productListElement = document.getElementById("productList");
const cartItemsElement = document.getElementById("cartItems");
const cartTotalElement = document.getElementById("cartTotal");
const emptyCartTextElement = document.getElementById("emptyCartText");
const checkoutButton = document.getElementById("checkoutButton");
const originalCheckoutButtonText = checkoutButton ? checkoutButton.textContent : "Finalizar Pedido";
const chatMessagesElement = document.getElementById("chatMessages");
const chatInputElement = document.getElementById("chatInput");
const sendChatButton = document.getElementById("sendChatButton");
const aiLoadingIndicator = document.getElementById("aiLoadingIndicator");
// --- Modales ---
const welcomeModal = document.getElementById("welcomeModal");
const startOrderButton = document.getElementById("startOrderButton");
const userNameInput = document.getElementById("userNameInput");
const userTableInput = document.getElementById("userTableInput");
const orderConfirmationModal = document.getElementById("orderConfirmationModal");
const closeConfirmationModalButton = document.getElementById("closeConfirmationModalButton");
const orderErrorModal = document.getElementById("orderErrorModal");
const closeOrderErrorModalButton = document.getElementById("closeOrderErrorModalButton");
const newOrderButton = document.getElementById("newOrderButton");
const retryButton = document.getElementById("retryButton");
// --- Loader Global ---
let globalLoaderElement = null;
function createGlobalLoader() {
if (document.getElementById('globalLoader')) return;
globalLoaderElement = document.createElement('div');
globalLoaderElement.id = 'globalLoader';
globalLoaderElement.className = 'fixed inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center z-[2000] transition-opacity duration-300 ease-in-out pointer-events-none';
globalLoaderElement.style.opacity = '0';
globalLoaderElement.innerHTML = `
Procesando su pedido...
`;
document.body.appendChild(globalLoaderElement);
}
function showGlobalLoader() {
if (!globalLoaderElement) createGlobalLoader();
globalLoaderElement.style.display = 'flex';
setTimeout(() => { if (globalLoaderElement) globalLoaderElement.style.opacity = '1'; }, 10);
}
function hideGlobalLoader() {
if (globalLoaderElement) {
globalLoaderElement.style.opacity = '0';
setTimeout(() => { if (globalLoaderElement) globalLoaderElement.style.display = 'none'; }, 300);
}
}
document.getElementById("currentYear").textContent = new Date().getFullYear().toString();
function formatPrice(price) {
return price.toLocaleString("es-CL", { style: "currency", currency: "CLP" });
}
async function processOrder() {
if (cart.length === 0) return;
showGlobalLoader();
if (checkoutButton) {
checkoutButton.disabled = true;
checkoutButton.textContent = "Procesando...";
}
try {
const orderData = {
customerName: userName,
table: userTable,
items: cart.map(item => ({ id: item.id, name: item.name, quantity: item.quantity, price: item.price, itemTotal: item.price * item.quantity })),
totalAmount: cart.reduce((sum, item) => sum + item.price * item.quantity, 0),
orderDate: new Date().toISOString(),
};
console.log("Enviando Pedido:", orderData);
await sendOrder(orderData);
if (orderConfirmationModal) orderConfirmationModal.style.display = "flex";
} catch (error) {
console.error("Error al procesar la orden:", error);
if (orderErrorModal) {
const errorMessageElement = orderErrorModal.querySelector('p.text-lg');
if (errorMessageElement) {
errorMessageElement.textContent = `Hubo un problema: ${error.message || "Por favor, inténtalo de nuevo."}`;
}
orderErrorModal.style.display = "flex";
}
} finally {
hideGlobalLoader();
if (checkoutButton) {
checkoutButton.disabled = cart.length === 0;
checkoutButton.textContent = originalCheckoutButtonText;
}
}
}
async function renderProducts() {
if (!productListElement) return;
productListElement.innerHTML = "";
products = await getProducts();
products.forEach(product => {
const productCardContainer = document.createElement('div');
productCardContainer.innerHTML = `
`;
productListElement.appendChild(productCardContainer.firstElementChild);
});
document.querySelectorAll('.add-to-cart-btn').forEach(button => {
button.addEventListener('click', (event) => {
const productId = parseInt(event.target.closest('button').dataset.productId);
addToCart(productId, event.target.closest('button'));
});
});
}
window.addToCart = async (productId, buttonElement = null) => {
const product = products.find(p => p.id === productId);
if (!product) return;
const cartItem = cart.find(item => item.id === productId);
if (cartItem) {
cartItem.quantity++;
} else {
cart.push({ ...product, quantity: 1 });
}
if (buttonElement) {
const originalText = buttonElement.textContent;
buttonElement.textContent = "✔ Agregado!";
buttonElement.classList.replace('bg-accent-red', 'bg-green-500');
buttonElement.classList.remove("hover:bg-red-700");
buttonElement.disabled = true;
setTimeout(() => {
buttonElement.textContent = originalText;
buttonElement.classList.replace('bg-green-500', 'bg-accent-red');
buttonElement.classList.add("hover:bg-red-700");
buttonElement.disabled = false;
}, 1500);
}
updateCartDisplay();
};
window.removeFromCart = (productId, removeAll = false) => {
const itemIndex = cart.findIndex(item => item.id === productId);
if (itemIndex > -1) {
if (removeAll || cart[itemIndex].quantity === 1) {
cart.splice(itemIndex, 1);
} else {
cart[itemIndex].quantity--;
}
}
updateCartDisplay();
};
function updateCartDisplay() {
if (!cartItemsElement || !emptyCartTextElement || !checkoutButton) return;
cartItemsElement.innerHTML = "";
if (cart.length === 0) {
emptyCartTextElement.classList.remove("hidden");
checkoutButton.disabled = true;
} else {
emptyCartTextElement.classList.add("hidden");
checkoutButton.disabled = false;
cart.forEach(item => {
const cartItemHTML = `
${item.name} (x${item.quantity})
${formatPrice(item.price * item.quantity)}
`;
cartItemsElement.innerHTML += cartItemHTML;
});
}
calculateTotal();
}
function calculateTotal() {
if (!cartTotalElement) return;
const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
cartTotalElement.textContent = formatPrice(total);
}
// --- Lógica del Chat ---
function displayChatMessage(sender, message) {
if (!chatMessagesElement) return;
const bubbleClass = sender === "user" ? "chat-bubble-user" : "chat-bubble-ai";
const messageDiv = document.createElement("div");
messageDiv.classList.add("chat-bubble", bubbleClass);
messageDiv.innerHTML = sender === "ai" && window.marked ? marked.parse(message) : message;
chatMessagesElement.appendChild(messageDiv);
chatMessagesElement.scrollTop = chatMessagesElement.scrollHeight;
}
async function sendMessageToAI() {
if (!chatInputElement || !aiLoadingIndicator) return;
const userInput = chatInputElement.value.trim();
if (!userInput) return;
displayChatMessage("user", userInput);
chatInputElement.value = '';
aiLoadingIndicator.classList.remove("hidden");
try {
const response = await serviceSendMessage(userInput, chatHistory);
if (!response) {
displayChatMessage("ai", "Hubo un problema al conectar con el Chef IA.");
} else if (response === "not_init") {
displayChatMessage("ai", "El chat no está inicializado. Intentando reconectar...");
if (await serviceInitializeChat()) {
displayChatMessage("ai", "Reconexión exitosa. Por favor, envía tu mensaje de nuevo.");
} else {
displayChatMessage("ai", "Fallo la reconexión. Por favor, refresca la página.");
}
} else if (response.assistantResponse) {
chatHistory = response.messageList;
displayChatMessage("ai", response.assistantResponse);
}
} catch (error) {
console.error("Error enviando mensaje a IA:", error);
displayChatMessage("ai", `Error: ${error.message || "No se pudo conectar con el Chef IA."}`);
} finally {
aiLoadingIndicator.classList.add("hidden");
if (chatInputElement) chatInputElement.focus();
}
}
// --- Event Listeners ---
document.addEventListener("DOMContentLoaded", async () => {
createGlobalLoader();
updateCartDisplay();
if (welcomeModal && startOrderButton) {
startOrderButton.onclick = () => {
const name = userNameInput.value.trim();
const table = userTableInput.value;
if (name && table) {
userName = name;
userTable = parseInt(table);
welcomeModal.style.display = 'none';
// Iniciar la app después de obtener los datos
initializeApp();
} else {
alert('Por favor, ingresa tu nombre y número de mesa para continuar.');
}
}
}
async function initializeApp() {
await renderProducts();
try {
if (await serviceInitializeChat()) {
console.log("Chat AI Asistente inicializado exitosamente.");
} else {
console.warn("Chat AI no pudo inicializarse.");
displayChatMessage("ai", "No se pudo conectar con el Chef IA en este momento.");
}
} catch (error) {
console.error("Error durante la inicialización del Chat AI:", error);
displayChatMessage("ai", "Error al iniciar el Chef IA.");
}
}
});
if (checkoutButton) checkoutButton.addEventListener("click", processOrder);
if (closeConfirmationModalButton) closeConfirmationModalButton.addEventListener("click", () => { orderConfirmationModal.style.display = "none"; });
if (closeOrderErrorModalButton) closeOrderErrorModalButton.addEventListener("click", () => { orderErrorModal.style.display = "none"; });
if (newOrderButton) {
newOrderButton.addEventListener("click", () => {
orderConfirmationModal.style.display = "none";
cart = [];
updateCartDisplay();
});
}
if (retryButton) retryButton.addEventListener("click", () => { orderErrorModal.style.display = "none"; });
if (sendChatButton) sendChatButton.addEventListener("click", sendMessageToAI);
if (chatInputElement) {
chatInputElement.addEventListener("keypress", (event) => {
if (event.key === "Enter") {
event.preventDefault();
sendMessageToAI();
}
});
}