مشاور هوشمند پیشرفته | ویراژ خودرو

مشاور هوشمند ویراژ خودرو

با پاسخ به چند سؤال، بهترین موتورسیکلت را برای خود پیدا کنید

`; } showError(message) { this.advisorBody.innerHTML = `

خطا: ${esc(message)}

لطفاً صفحه را دوباره بارگذاری کنید.

PRICES_URL: ${esc(buildUrlWithBust(SETTINGS.PRICES_URL))}
`; } async fetchPrices() { const url = buildUrlWithBust(SETTINGS.PRICES_URL); const response = await fetch(url, { cache: "no-store", credentials: "same-origin", headers: { "Accept": "application/json" } }); if (!response.ok) { throw new Error(`خطا در دریافت قیمت‌ها: HTTP ${response.status} | ${url}`); } let data; try { data = await response.json(); } catch (e) { throw new Error(`فایل قیمت‌ها JSON معتبر نیست | ${url}`); } if (!data || typeof data !== "object") { throw new Error(`ساختار فایل قیمت‌ها نامعتبر است | ${url}`); } return data; } renderStep() { if (this.currentStep >= QUESTIONS.length) { this.showResults(); return; } const question = QUESTIONS[this.currentStep]; const progressPercent = (this.currentStep / QUESTIONS.length) * 100; const optionsHTML = question.options.map(opt => { const isVisual = question.isVisual; const btnClass = `option-btn ${isVisual ? 'visual' : ''}`; const bgImage = isVisual ? `style="background-image: url(${opt.imageUrl})"` : ''; const iconHTML = !isVisual ? `${opt.icon}` : ''; return `
${isVisual ? '
' : ''} ${iconHTML}
${esc(opt.label)}
`; }).join(''); this.advisorBody.innerHTML = `
مرحله ${this.currentStep + 1} از ${QUESTIONS.length}

${esc(question.title)}

${esc(question.hint)}

${optionsHTML}
`; document.querySelectorAll('.option-btn').forEach(btn => btn.addEventListener('click', (e) => { document.querySelectorAll('.option-btn').forEach(b => b.classList.remove('selected')); e.currentTarget.classList.add('selected'); setTimeout(() => this.handleOptionSelect(question.id, btn.dataset.id), 200); }) ); const prevBtn = document.getElementById('prevBtn'); if (prevBtn) prevBtn.addEventListener('click', () => this.prevStep()); } handleOptionSelect(questionId, optionId) { const question = QUESTIONS.find(q => q.id === questionId); const option = question?.options?.find(o => o.id === optionId); // دفاع: اگر چیزی اشتباه بود، سقوط نکن if (!question || !option) return; this.answers[questionId] = option.value; this.nextStep(); } nextStep() { this.currentStep++; this.renderStep(); } prevStep() { if (this.currentStep > 0) { this.currentStep--; const questionId = QUESTIONS[this.currentStep].id; delete this.answers[questionId]; this.renderStep(); } } calculateResults() { const priority = this.answers.priority || 'price'; const scoredProducts = this.products.map(product => { let score = 0; let strictMatches = 0; // 1) Strict Filters for (const question of QUESTIONS.filter(q => q.type === 'strict_filter')) { const answerValue = this.answers[question.id]; if (answerValue && answerValue !== 'any') { if (question.filter(product, answerValue)) { score += 100; strictMatches++; } } } // 2) Scoring Filters for (const question of QUESTIONS.filter(q => q.type === 'scoring')) { const answerValue = this.answers[question.id]; if (answerValue) score += question.score(product, answerValue); } // 3) Priority Scoring if (priority === 'power') { if (product.specs.engine_cc > 180) score += 5; if (product.tags.use_case.includes('sport')) score += 5; } if (priority === 'comfort') { if (product.tags.features.includes('abs_brakes')) score += 3; if (product.tags.features.includes('digital_display')) score += 2; if (product.specs.category === 'scooter' || product.specs.category === 'cruiser') score += 3; } if (priority === 'maintenance') { if (product.tags.features.includes('low_maintenance')) score += 10; } // اگر priority قیمت بود، کمی امتیاز به ارزان‌ترها بده if (priority === 'price') { // قیمت کمتر => امتیاز بیشتر (نرمال‌سازی ساده) const p = product.price; if (p > 0) score += Math.max(0, 20 - p / 10); } return { product, score, strictMatches }; }); return scoredProducts.sort((a, b) => b.score - a.score); } showResults() { const results = this.calculateResults(); const topResults = results.slice(0, SETTINGS.RECOMMENDATION_COUNT); this.advisorBody.innerHTML = `
نتیجه نهایی
`; let resultsHeader = `

بهترین پیشنهادها برای شما

`; const totalStrictQuestionsAnswered = Object.keys(this.answers).filter(key => { const q = QUESTIONS.find(q => q.id === key); return q && q.type === 'strict_filter' && this.answers[key] !== 'any'; }).length; if (topResults.length > 0 && topResults[0].strictMatches < totalStrictQuestionsAnswered) { resultsHeader += `

نتیجه دقیقی یافت نشد. این‌ها نزدیک‌ترین گزینه‌ها بر اساس اولویت‌های شما هستند.

`; } const resultsHTML = topResults.length ? topResults.map(item => this.getProductCardHTML(item.product)).join('') : `

متاسفانه محصولی در حال حاضر موجود نیست. می‌توانید دوباره امتحان کنید.

`; this.advisorBody.innerHTML += `
${resultsHeader}
${resultsHTML}
`; const restartBtn = document.getElementById('restartBtn'); if (restartBtn) { restartBtn.addEventListener('click', () => { this.currentStep = 0; this.answers = {}; this.renderStep(); }); } } getProductCardHTML(product) { const transmissionIcon = product.specs.transmission_type === 'automatic' ? `` : ``; const formatter = new Intl.NumberFormat('fa-IR'); const longestTerm = SETTINGS.LONGEST_TERM_MONTHS; const minMonthlyPayment = ((product.price * SETTINGS.MONTHLY_INTEREST_RATE * longestTerm) + product.price) / longestTerm; const formattedInstallment = formatter.format(Math.round(minMonthlyPayment * 100) / 100); return `
${esc(product.name)}

${esc(product.name)}

${esc(product.brand)}

${transmissionIcon} ${product.specs.transmission_type === 'automatic' ? 'اتوماتیک' : 'دنده‌ای'}
${formatter.format(product.specs.engine_cc)} سی‌سی

${formatter.format(product.price)} میلیون تومان

شروع اقساط از ماهانه ${formattedInstallment} میلیون تومان

`; } } new AdvisorApp();