`;
// --- Scenario 2: Invest the Lump Sum ---
const comparisonYears = origRemainingTermMonths / 12;
const fvLumpSumInvestment = pvi_calculateFutureValue(lumpSum, investmentReturnAnnualRate, comparisonYears, true);
const netGainInvestment = fvLumpSumInvestment - lumpSum;
resultsHTML += `
Scenario 2: Invest ${pvi_formatCurrency(lumpSum)} Instead
`;
resultsHTML += `
Lump Sum Invested: ${pvi_formatCurrency(lumpSum)}
`;
resultsHTML += `
For: ${origRemainingTermMonths} months (${comparisonYears.toFixed(1)} years)
`;
resultsHTML += `
At Expected Net Annual Return: ${pvi_formatPercent(investmentReturnAnnualRate)}
`;
resultsHTML += `
Future Value of Investment: ${pvi_formatCurrency(fvLumpSumInvestment)}
`;
resultsHTML += `
Net Gain from Investment (after ${origRemainingTermMonths} months): ${pvi_formatCurrency(netGainInvestment)}
`;
resultsHTML += `
Note: During this period, you would continue making your original loan payments, incurring ${pvi_formatCurrency(totalInterestWithoutPrepayment)} in loan interest.
`;
// --- Final Summary ---
if (totalBenefitPrepayment > netGainInvestment) {
finalSummaryText = `Prepaying the loan appears to provide a greater financial benefit of approximately ${pvi_formatCurrency(totalBenefitPrepayment - netGainInvestment)} over investing the lump sum in this scenario.`;
finalSummaryClass = "pvi-summary-better";
} else if (netGainInvestment > totalBenefitPrepayment) {
finalSummaryText = `Investing the lump sum appears to provide a greater financial benefit of approximately ${pvi_formatCurrency(netGainInvestment - totalBenefitPrepayment)} over prepaying the loan in this scenario. Consider the risks associated with investments.`;
finalSummaryClass = "pvi-summary-better";
} else {
finalSummaryText = "Both options provide a similar estimated financial benefit in this scenario. Consider other factors like risk tolerance and cash flow needs.";
finalSummaryClass = "pvi-summary-neutral";
}
if(pvi_el.resultsComparisonDiv) pvi_el.resultsComparisonDiv.innerHTML = resultsHTML;
if(pvi_el.finalSummaryDiv) {
pvi_el.finalSummaryDiv.textContent = finalSummaryText;
pvi_el.finalSummaryDiv.className = finalSummaryClass;
}
if(pvi_el.pdfDownloadBtn && pvi_el.pdfDownloadBtn.style) pvi_el.pdfDownloadBtn.style.display = 'block';
}
function pvi_resetForm() {
if(pvi_el.loanBalance) pvi_el.loanBalance.value = "15000";
if(pvi_el.loanAPR) pvi_el.loanAPR.value = "7.0";
if(pvi_el.remainingTerm) pvi_el.remainingTerm.value = "36";
pvi_calculateCurrentMonthlyPayment();
if(pvi_el.lumpSum) pvi_el.lumpSum.value = "5000";
if(pvi_el.investmentReturnRate) pvi_el.investmentReturnRate.value = "8.0";
document.querySelectorAll('#prepayVsInvestAnalyzer .pvi-error-message').forEach(el => el.textContent = '');
if(pvi_el.resultsComparisonDiv) pvi_el.resultsComparisonDiv.innerHTML = "";
if(pvi_el.finalSummaryDiv) { pvi_el.finalSummaryDiv.textContent = ""; pvi_el.finalSummaryDiv.className = ""; }
if(pvi_el.comparisonPeriodDisplay) pvi_el.comparisonPeriodDisplay.textContent = "X";
if(pvi_el.pdfDownloadBtn && pvi_el.pdfDownloadBtn.style) pvi_el.pdfDownloadBtn.style.display = 'none';
if(pvi_el.resultsTabButton) pvi_el.resultsTabButton.disabled = true;
pvi_currentTab = 0;
pvi_openTab(null, 'pvi-tabLoan');
}
function pvi_downloadPDF() {
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF !== 'function' || typeof window.html2canvas !== 'function') {
alert("PDF generation library (jsPDF/html2canvas) not loaded. Check CDN links & internet."); return;
}
const jsPDFConstructor = window.jspdf.jsPDF;
const resultsToCapture = pvi_el.resultsComparisonDiv;
const finalSummaryToCapture = pvi_el.finalSummaryDiv;
const disclaimerContent = document.querySelector('#prepayVsInvestAnalyzer .pvi-disclaimer-note');
if (!resultsToCapture || !resultsToCapture.innerHTML.trim() || !finalSummaryToCapture || !finalSummaryToCapture.textContent.trim()) {
alert("No results to download. Please analyze first."); return;
}
const pdf = new jsPDFConstructor('p', 'pt', 'a4');
const toolTitle = "Loan Prepayment vs. Investment Analysis";
const margins = { top: 40, bottom: 40, left: 30, right: 30 };
let yPos = margins.top;
pdf.setFontSize(18);
pdf.text(toolTitle, pdf.internal.pageSize.getWidth() / 2, yPos, { align: 'center' });
yPos += 30;
// Inputs Summary
pdf.setFontSize(11);
pdf.text("Inputs Summary:", margins.left, yPos); yPos += 15;
pdf.setFontSize(9);
pdf.text(`- Loan Balance: ${pvi_formatCurrency(parseFloat(pvi_el.loanBalance.value))}, APR: ${pvi_el.loanAPR.value}%, Rem. Term: ${pvi_el.remainingTerm.value} months`, margins.left + 10, yPos); yPos += 13;
pdf.text(`- Lump Sum: ${pvi_formatCurrency(parseFloat(pvi_el.lumpSum.value))}, Est. Investment Return: ${pvi_el.investmentReturnRate.value}% net APR`, margins.left + 10, yPos); yPos += 20;
// Use html2canvas for the results section for better formatting preservation
html2canvas(resultsToCapture, {scale: 1.2, backgroundColor: '#ffffff', useCORS: true, windowWidth: resultsToCapture.scrollWidth}).then(canvasResults => {
const imgDataResults = canvasResults.toDataURL('image/png');
const imgPropsResults = pdf.getImageProperties(imgDataResults);
const pdfWidth = pdf.internal.pageSize.getWidth() - margins.left - margins.right;
let pdfHeightResults = (imgPropsResults.height * pdfWidth) / imgPropsResults.width;
if (yPos + pdfHeightResults > pdf.internal.pageSize.getHeight() - margins.bottom - 30) {
pdf.addPage(); yPos = margins.top;
}
pdf.addImage(imgDataResults, 'PNG', margins.left, yPos, pdfWidth, pdfHeightResults);
yPos += pdfHeightResults + 15;
// Final Summary section via html2canvas
html2canvas(finalSummaryToCapture, {scale:1.5, backgroundColor: '#ffffff', useCORS: true}).then(canvasSummary => {
const imgDataSummary = canvasSummary.toDataURL('image/png');
const imgPropsSummary = pdf.getImageProperties(imgDataSummary);
let pdfHeightSummary = (imgPropsSummary.height * pdfWidth) / imgPropsSummary.width;
if (yPos + pdfHeightSummary > pdf.internal.pageSize.getHeight() - margins.bottom - 30) {
pdf.addPage(); yPos = margins.top;
}
pdf.addImage(imgDataSummary, 'PNG', margins.left, yPos, pdfWidth, pdfHeightSummary);
yPos += pdfHeightSummary + 20;
if (disclaimerContent) {
if (yPos > pdf.internal.pageSize.getHeight() - margins.bottom - 40) {
pdf.addPage(); yPos = margins.top;
}
pdf.setFontSize(8);
const disclaimerLines = pdf.splitTextToSize(disclaimerContent.innerText.trim(), pdf.internal.pageSize.getWidth() - margins.left - margins.right);
pdf.text(disclaimerLines, margins.left, yPos);
}
pdf.save('Prepayment_vs_Investment_Analysis.pdf');
});
}).catch(err => {
console.error("Error generating PDF with html2canvas:", err);
alert("Error generating PDF. See console for details.");
});
}