`;
}
if (nextButton) {
nextButton.addEventListener('click', () => {
let canProceed = false;
if (currentTab === 0) {
canProceed = validateTab1();
} else if (currentTab === 1) {
canProceed = validateAndCalculateTab2();
} else if (currentTab === 2) {
canProceed = validateAndCalculateTab3();
if (canProceed) populateComparison();
}
if (canProceed && currentTab < tabContents.length - 1) {
showTab(currentTab + 1);
}
});
}
if (prevButton) {
prevButton.addEventListener('click', () => {
if (currentTab > 0) {
showTab(currentTab - 1);
// Clear errors on tabs when going back
[errorTab1El, errorTab2El, errorTab3El, errorTab4El].forEach(clearError);
}
});
}
if (tabButtons) {
tabButtons.forEach((button, index) => {
button.addEventListener('click', () => {
if (index <= currentTab) { // Allow navigation to previous/current tabs
showTab(index);
} else { // Attempt to fast-forward if clicking a future tab
let canReachTarget = true;
for (let i = currentTab; i < index; i++) {
let validationPassed = false;
if (i === 0) validationPassed = validateTab1();
else if (i === 1) validationPassed = validateAndCalculateTab2();
else if (i === 2) {
validationPassed = validateAndCalculateTab3();
if (validationPassed) populateComparison();
}
if (!validationPassed) {
showTab(i); // Stay on the tab that failed
if (nextButton) nextButton.click(); // Simulate next to show error
canReachTarget = false;
break;
}
}
if (canReachTarget) showTab(index);
}
});
});
}
if (downloadPdfButton) {
downloadPdfButton.addEventListener('click', () => {
clearError(errorTab4El);
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
displayError(errorTab4El, 'PDF library (jsPDF) not loaded.'); console.error('window.jspdf or window.jspdf.jsPDF is undefined.'); return;
}
const JSPDFConstructor = window.jspdf.jsPDF;
const doc = new JSPDFConstructor();
if (typeof doc.autoTable !== 'function') {
displayError(errorTab4El, 'PDF table plugin (autoTable) not loaded.'); console.error('doc.autoTable is not a function.'); return;
}
if (!comparisonData.loan.totalCost === undefined || !comparisonData.rbf.totalCost === undefined) {
displayError(errorTab4El, 'Please complete all steps for comparison data before PDF generation.'); return;
}
const loan = comparisonData.loan;
const rbf = comparisonData.rbf;
const funding = comparisonData.fundingAmount;
const avgRevenue = comparisonData.avgMonthlyRevenue;
const formatPdfCurrency = (num) => (typeof num !== 'number' || isNaN(num)) ? '$0.00' : `$${num.toFixed(2)}`;
const formatPdfNumber = (num, dec=2) => (typeof num !== 'number' || isNaN(num)) ? 'N/A' : num.toFixed(dec);
doc.setFontSize(18);
doc.text("Business Financing Cost Comparison", 14, 20);
doc.setFontSize(10);
doc.setTextColor(100);
doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, 27);
doc.setTextColor(0);
const headStyles = { fillColor: [0, 115, 170], textColor: 255, fontStyle: 'bold' };
const subHeadStyles = { fillColor: [230, 230, 230], textColor: 0, fontStyle: 'bold' };
const theme = 'grid';
let startY = 35;
// Input Summary
doc.setFontSize(12);
doc.text("Initial Assumptions", 14, startY); startY += 6;
doc.autoTable({
startY: startY,
body: [
['Funding Amount Needed:', formatPdfCurrency(funding)],
['Est. Average Monthly Revenue:', formatPdfCurrency(avgRevenue)],
],
theme: 'plain', columnStyles: { 0: { fontStyle: 'bold' } }
});
startY = doc.lastAutoTable.finalY + 8;
// Comparison Table
doc.setFontSize(12);
doc.text("Financing Option Comparison", 14, startY); startY += 2;
const tableData = [
[{content: 'Metric', styles: {fontStyle: 'bold'}}, {content: 'Traditional Loan', styles: {halign: 'center'}}, {content: 'Revenue-Based Financing', styles: {halign: 'center'}}],
['Funding Amount', formatPdfCurrency(funding), formatPdfCurrency(funding)],
['Annual Interest Rate / Cap', `${formatPdfNumber(loan.interestRate)}%` , `${formatPdfNumber(rbf.repaymentCap)}x Cap`],
['Term / Revenue Share', `${formatPdfNumber(loan.termYears,1)} yrs (${formatPdfNumber(loan.termMonths,0)} mos)` , `${formatPdfNumber(rbf.revenueShare)}% Share`],
['Upfront Fees', formatPdfCurrency(loan.calculatedUpfrontFee), formatPdfCurrency(rbf.calculatedUpfrontFee)],
['Monthly Payment', `${formatPdfCurrency(loan.monthlyPayment)} (Fixed)`, `${formatPdfCurrency(rbf.estimatedMonthlyPayment)} (Est. Avg)`],
['Est. Repayment Term', `${formatPdfNumber(loan.termMonths,0)} mos`, rbf.estimatedRepaymentMonths === Infinity ? 'N/A' : `${formatPdfNumber(rbf.estimatedRepaymentMonths,1)} mos (Est.)`],
['Total Interest / Premium', formatPdfCurrency(loan.totalInterest), formatPdfCurrency(rbf.totalRepayment - funding)],
[{content: 'Total Cost of Financing', styles:{fontStyle:'bold'}}, {content:formatPdfCurrency(loan.totalCost), styles:{fontStyle:'bold'}}, {content:formatPdfCurrency(rbf.totalCost), styles:{fontStyle:'bold'}}],
[{content: 'Total Amount Repaid', styles:{fontStyle:'bold'}}, {content:formatPdfCurrency(loan.totalRepayment), styles:{fontStyle:'bold'}}, {content:formatPdfCurrency(rbf.totalRepayment), styles:{fontStyle:'bold'}}]
];
doc.autoTable({
startY: startY,
head: tableData.slice(0,1), // Use first row as head
body: tableData.slice(1), // Rest as body
theme: theme,
headStyles: headStyles,
columnStyles: {0:{cellWidth:55}, 1:{halign:'right', cellWidth:55}, 2:{halign:'right', cellWidth:55}},
margin: {left: 14, right: 14}
});
startY = doc.lastAutoTable.finalY + 10;
doc.setFontSize(9);
doc.setTextColor(100);
const noteText = "This comparison is an estimate based on the inputs provided. Actual terms and costs may vary significantly. This tool does not provide financial advice; consult with a financial advisor before making decisions.";
const splitNoteText = doc.splitTextToSize(noteText, doc.internal.pageSize.width - 28);
doc.text(splitNoteText, 14, startY);
doc.save("Financing_Comparison_Summary.pdf");
});
}
// Initialize
if (tabContents.length > 0 && tabButtons.length > 0) showTab(0);
if (fundingAmountEl) fundingAmountEl.addEventListener('input', updateFundingDisplays);
updateFundingDisplays(); // Initial call
});
