`);
});
}
// --- SPEECH & COMMAND LOGIC ---
function setupSpeechRecognition() {
if (SpeechRecognition) {
recognition = new SpeechRecognition();
recognition.continuous = false;
recognition.lang = 'en-US';
recognition.onstart = () => { isListening = true; micBtn.classList.add('listening'); };
recognition.onresult = (event) => { handleUserInput(event.results[0][0].transcript); };
recognition.onerror = (event) => { addMessageToChat('assistant', `Error: ${event.error}. Please try again.`); };
recognition.onend = () => { isListening = false; micBtn.classList.remove('listening'); };
} else {
addMessageToChat('assistant', "Sorry, your browser doesn't support speech recognition.");
micBtn.disabled = true;
}
}
function handleUserInput(text) {
addMessageToChat('user', text);
processCommand(text);
}
function processCommand(command) {
command = command.toLowerCase();
if (command.includes('search for') || command.includes('find') || command.includes('show me')) {
let query = command.replace(/search for|find|show me/g, '').trim();
if (query.endsWith('s')) { // Simple plural to singular for better matching
query = query.slice(0, -1);
}
lastSearchQuery = query;
const results = productCatalog.filter(p => p.keywords.some(k => k.includes(query)));
lastSearchResults = results;
renderProducts(results);
const response = `I found ${results.length} ${query} products for you.`;
addMessageToChat('assistant', response);
speak(response);
downloadPdfBtn.disabled = results.length === 0;
} else {
const response = "I can help you search for products. Try saying 'find laptops' or 'show me headphones'.";
addMessageToChat('assistant', response);
speak(response);
}
}
// --- EVENT HANDLERS ---
micBtn.addEventListener('click', () => {
if (isListening) {
recognition.stop();
} else {
recognition.start();
}
});
chatForm.addEventListener('submit', (e) => {
e.preventDefault();
const text = chatInput.value.trim();
if (text) {
handleUserInput(text);
chatInput.value = '';
}
});
downloadPdfBtn.addEventListener('click', generatePdf);
// --- PDF GENERATION ---
async function generatePdf() {
const { jsPDF } = window.jspdf;
const pdfReportElement = document.getElementById('pdf-report');
document.getElementById('pdf-date').textContent = new Date().toLocaleDateString('en-US');
document.getElementById('pdf-query').textContent = lastSearchQuery;
const pdfTableBody = document.getElementById('pdf-table-body');
pdfTableBody.innerHTML = '';
lastSearchResults.forEach(p => {
pdfTableBody.insertAdjacentHTML('beforeend', `
| ${p.name} | ${p.category} | ${p.price.toFixed(2)} |
`);
});
const canvas = await html2canvas(pdfReportElement, { scale: 2 });
const imgData = canvas.toDataURL('image/jpeg', 0.85);
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);
pdf.save(`Shopping-Search-${lastSearchQuery}.pdf`);
}
// --- INITIALIZATION ---
function init() {
renderProducts(productCatalog); // Show all products initially
setupSpeechRecognition();
const welcome = "Hello! How can I help you shop today?";
addMessageToChat('assistant', welcome);
speak(welcome);
}
init();
});