`;
if (elementId === 'standardPlanResults') { // Main container for potentially two summaries
let comparisonHTML = summaryHTML; // Start with standard
if (document.getElementById('acceleratedPlanResults').style.display === 'block' && standardPlanForComparison === null) {
// This means we're calling for accelerated, so standard is already there.
// The structure is for standardPlanResults to hold standard, acceleratedPlanResults to hold accelerated
}
container.innerHTML = comparisonHTML;
} else { // This is for accelerated plan specifically
container.innerHTML = summaryHTML;
}
// If standardPlanResults is being updated, and there's an accelerated plan, it should be in its own div
if (elementId === 'standardPlanResults' && loanAnalysisData.acceleratedPlan && standardPlanForComparison === null) {
// Standard plan is displayed in standardPlanResults.
// Accelerated plan will be (re)displayed by its own call to displayPlanSummary.
} else if (elementId === 'acceleratedPlanResults') {
//This ensures the comparison section properly wraps both if accelerated plan exists
document.getElementById('standardPlanResults').innerHTML = loanAnalysisData.standardPlan ?
displayPlanSummaryHTML(loanAnalysisData.standardPlan, "Standard Repayment Plan") : '';
container.innerHTML = displayPlanSummaryHTML(planData, title, loanAnalysisData.standardPlan);
// Wrap both in the comparison section div
const finalLayout = `
${document.getElementById('standardPlanResults').innerHTML}${container.innerHTML}
`;
document.getElementById('resultsContainer').querySelector('h3').insertAdjacentHTML('afterend', finalLayout);
// Clear the individual containers as they are now part of comparison-section
document.getElementById('standardPlanResults').innerHTML = '';
document.getElementById('acceleratedPlanResults').innerHTML = '';
} else if (elementId === 'standardPlanResults' && !loanAnalysisData.acceleratedPlan) {
// Only standard plan
container.innerHTML = `
${summaryHTML}
`;
}
}
// Helper function to return HTML string for plan summary, to manage layout better
function displayPlanSummaryHTML(planData, title, standardPlanForComparison = null) {
let summaryHTML = `
${title}
`;
const baseEMI = loanAnalysisData.standardPlan ? loanAnalysisData.standardPlan.monthlyEMI : planData.monthlyEMI;
const currentExtraPayment = (planData.effectiveMonthlyPayment && baseEMI) ? planData.effectiveMonthlyPayment - baseEMI : 0;
summaryHTML += `
Monthly Payment: $${(planData.effectiveMonthlyPayment || planData.monthlyEMI).toFixed(2)}
`;
if(title.includes("Accelerated") && currentExtraPayment > 0) {
summaryHTML += `
(Std EMI: $${baseEMI.toFixed(2)} + Extra: $${currentExtraPayment.toFixed(2)})
`;
}
if(title.includes("Accelerated") && planData.lumpSumAmount > 0) {
summaryHTML += `
(Incl. Lump Sum of $${planData.lumpSumAmount.toFixed(2)} in month ${planData.lumpSumMonth})
`;
}
summaryHTML += `
Loan Payoff Time: ${Math.floor(planData.payoffTimeMonths / 12)} yrs, ${planData.payoffTimeMonths % 12} mths (${planData.payoffTimeMonths} mths)
`;
summaryHTML += `
Total Interest Paid: $${planData.totalInterest.toFixed(2)}
`;
summaryHTML += `
Total Amount Paid: $${planData.totalAmount.toFixed(2)}
`;
summaryHTML += `
Estimated Payoff Date: ${planData.payoffDate}
`;
if (standardPlanForComparison && planData.interestSaved !== undefined) {
summaryHTML += `
`;
summaryHTML += `
Savings Achieved:
`;
summaryHTML += `
Interest Saved: $${planData.interestSaved.toFixed(2)}
`;
const timeSavedY = Math.floor(planData.timeSavedMonths / 12);
const timeSavedM = planData.timeSavedMonths % 12;
summaryHTML += `
Time Saved: ${timeSavedY} yr${timeSavedY !== 1 ? 's' : ''}, ${timeSavedM} mth${timeSavedM !== 1 ? 's' : ''} (${planData.timeSavedMonths} mths)
`;
}
summaryHTML += `
`;
return summaryHTML;
}
function displayAmortizationTable(schedule) {
const container = document.getElementById('amortizationTableContainer');
if (!schedule || schedule.length === 0) {
container.innerHTML = "
No schedule data available.
";
return;
}
let tableHTML = `
| Month |
Beginning Balance |
Payment |
Interest |
Principal |
Lump Sum |
Ending Balance |
`;
schedule.forEach(row => {
tableHTML += `
| ${row.month} |
$${row.beginningBalance.toFixed(2)} |
$${row.payment.toFixed(2)} |
$${row.interest.toFixed(2)} |
$${row.principal.toFixed(2)} |
$${row.lumpSum.toFixed(2)} |
$${row.endingBalance.toFixed(2)} |
`;
});
tableHTML += `
`;
container.innerHTML = tableHTML;
}
function downloadLoanPdf() {
if (!loanAnalysisData.standardPlan) {
alert("Please calculate a plan first."); return;
}
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
alert('PDF generation library (jsPDF) is not loaded.'); return;
}
const jsPDFConstructor = window.jspdf.jsPDF;
const doc = new jsPDFConstructor();
if (typeof doc.autoTable !== 'function') {
alert('jsPDF AutoTable plugin not loaded.'); return;
}
const primaryColor = '#007bff'; textColor = '#212529', tableHeaderColor = '#e9ecef';
let yPos = 22;
doc.setFontSize(18); doc.setTextColor(primaryColor);
doc.text("Personal Loan Repayment Plan", 14, yPos); yPos += 8;
doc.setFontSize(10); doc.setTextColor(textColor);
doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, yPos); yPos += 10;
// Loan Inputs
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text("Loan Inputs", 14, yPos); yPos += 6;
const inputsBody = [
['Loan Amount:', `$${loanAnalysisData.standardPlan.principal.toFixed(2)}`],
['Annual Interest Rate:', `${loanAnalysisData.standardPlan.annualRate.toFixed(2)}%`],
['Loan Term:', `${loanAnalysisData.standardPlan.termYears} years (${loanAnalysisData.standardPlan.termYears * 12} months)`],
['Loan Start Date:', loanAnalysisData.standardPlan.startDateStr || 'Not specified']
];
if(loanAnalysisData.acceleratedPlan){
inputsBody.push(['Extra Monthly Payment:', `$${(document.getElementById('extraMonthlyPayment').valueAsNumber || 0).toFixed(2)}`]);
if((document.getElementById('lumpSumAmount').valueAsNumber || 0) > 0) {
inputsBody.push(['Lump Sum Payment:', `$${(document.getElementById('lumpSumAmount').valueAsNumber).toFixed(2)} (in month ${(document.getElementById('lumpSumMonth').valueAsNumber)})`]);
}
}
doc.autoTable({ startY: yPos, body: inputsBody, theme: 'plain', styles: {fontSize:9}, columnStyles: {0:{fontStyle:'bold'}}});
yPos = doc.lastAutoTable.finalY + 10;
// Plan Summaries
function addPlanSummaryToPdf(plan, title) {
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text(title, 14, yPos); yPos +=6;
const baseEMI_pdf = loanAnalysisData.standardPlan ? loanAnalysisData.standardPlan.monthlyEMI : plan.monthlyEMI;
const extraPay_pdf = (plan.effectiveMonthlyPayment && baseEMI_pdf) ? plan.effectiveMonthlyPayment - baseEMI_pdf : 0;
let planBody = [
['Monthly Payment:', `$${(plan.effectiveMonthlyPayment || plan.monthlyEMI).toFixed(2)}`],
];
if(title.includes("Accelerated") && extraPay_pdf > 0) {
planBody.push(['Breakdown:', `(Std EMI: $${baseEMI_pdf.toFixed(2)} + Extra: $${extraPay_pdf.toFixed(2)})`]);
}
if(title.includes("Accelerated") && plan.lumpSumAmount > 0) {
planBody.push(['Lump Sum:', `$${plan.lumpSumAmount.toFixed(2)} (Month ${plan.lumpSumMonth})`]);
}
planBody.push(...[
['Payoff Time:', `${Math.floor(plan.payoffTimeMonths / 12)} yrs, ${plan.payoffTimeMonths % 12} mths (${plan.payoffTimeMonths} mths)`],
['Total Interest Paid:', `$${plan.totalInterest.toFixed(2)}`],
['Total Amount Paid:', `$${plan.totalAmount.toFixed(2)}`],
['Est. Payoff Date:', plan.payoffDate]
]);
if(plan.interestSaved !== undefined) {
planBody.push(['--- Savings ---', '']);
planBody.push(['Interest Saved:', `$${plan.interestSaved.toFixed(2)}`]);
planBody.push(['Time Saved:', `${Math.floor(plan.timeSavedMonths / 12)} yrs, ${plan.timeSavedMonths % 12} mths`]);
}
doc.autoTable({startY: yPos, body: planBody, theme:'plain', styles:{fontSize:9}, columnStyles: {0:{fontStyle:'bold'}}});
yPos = doc.lastAutoTable.finalY + 10;
}
addPlanSummaryToPdf(loanAnalysisData.standardPlan, "Standard Repayment Plan");
if(loanAnalysisData.acceleratedPlan){
if (yPos > 250) { doc.addPage(); yPos = 20; }
addPlanSummaryToPdf(loanAnalysisData.acceleratedPlan, "Accelerated Repayment Plan");
}
// Amortization Schedule
const scheduleToUse = loanAnalysisData.acceleratedPlan ? loanAnalysisData.acceleratedPlan.schedule : loanAnalysisData.standardPlan.schedule;
const scheduleTitle = loanAnalysisData.acceleratedPlan ? "Amortization Schedule (Accelerated Plan)" : "Amortization Schedule (Standard Plan)";
if (yPos > 240) { doc.addPage(); yPos = 20; } // Check space before starting table
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text(scheduleTitle, 14, yPos); yPos += 6;
const scheduleBody = scheduleToUse.map(row => [
row.month,
`$${row.beginningBalance.toFixed(2)}`,
`$${row.payment.toFixed(2)}`,
`$${row.interest.toFixed(2)}`,
`$${row.principal.toFixed(2)}`,
`$${row.lumpSum.toFixed(2)}`,
`$${row.endingBalance.toFixed(2)}`
]);
doc.autoTable({
startY: yPos,
head: [['Month', 'Beginning Bal.', 'Payment', 'Interest', 'Principal', 'Lump Sum', 'Ending Bal.']],
body: scheduleBody,
theme: 'grid',
headStyles: { fillColor: tableHeaderColor, textColor: textColor, fontStyle: 'bold', fontSize:8 },
styles: { fontSize: 7, cellPadding: 1.2, halign: 'right' },
columnStyles: { 0: {halign: 'center'} }
});
doc.save("Loan_Repayment_Plan.pdf");
}
// Initial call to set up tab navigation button states
updateLoanNavButtons();