This emerging market currently presents a relatively low debt risk profile. While conditions are favorable, emerging markets always carry some inherent volatility. Continuous vigilance is advised. Consider:
- Staying informed about global economic shifts.
- Periodically reviewing debt sustainability reports from international bodies.
- Exploring opportunities for long-term strategic engagement.
`;
}
// Display results
overallDebtRiskLevelSpan.textContent = overallDebtRiskLevel;
overallDebtRiskLevelSpan.className = `text-3xl font-extrabold ${riskLevelClass}`;
totalDebtRiskScoreSpan.textContent = totalRiskScore;
contributingFactorsList.innerHTML = ''; // Clear previous list
if (contributingFactors.length === 0) {
const li = document.createElement('li');
li.textContent = "No significant high-risk factors identified based on current inputs.";
contributingFactorsList.appendChild(li);
} else {
contributingFactors.forEach(factor => {
const li = document.createElement('li');
li.textContent = factor;
contributingFactorsList.appendChild(li);
});
}
recommendationsContentList.innerHTML = recommendationsText; // Inject recommendations
// Scroll to analysis results
document.getElementById('analysis-results').scrollIntoView({ behavior: 'smooth' });
}
/**
* Generates a PDF report of the tool's inputs and analysis results.
*/
async function generatePdf() {
// Show loading spinner
pdfSpinner.classList.remove('hidden');
downloadPdfBtn.disabled = true; // Disable button during PDF generation
// Ensure the analysis is performed and displayed
analyzeDebtRisk();
// Create a temporary div to render PDF content into
const pdfContentDiv = document.createElement('div');
pdfContentDiv.className = 'pdf-content-hidden'; // Hidden and styled for print
document.body.appendChild(pdfContentDiv);
// Add title to PDF content
const title = document.createElement('h1');
title.className = 'text-2xl font-bold text-gray-800 text-center mb-6';
title.textContent = 'AI-Powered Emerging Markets Debt Risk Report';
pdfContentDiv.appendChild(title);
// Helper to create a table for inputs
function createInputTable(titleText, inputsArray, currentValuesMap) {
const sectionTitle = document.createElement('h2');
sectionTitle.className = 'text-xl font-semibold text-gray-800 mb-4 mt-6';
sectionTitle.textContent = titleText;
pdfContentDiv.appendChild(sectionTitle);
const table = document.createElement('table');
table.className = 'w-full text-left border-collapse mb-6';
table.innerHTML = `
| Factor |
Value |
`;
const tableBody = table.querySelector('tbody');
pdfContentDiv.appendChild(table);
inputsArray.forEach(item => {
const row = tableBody.insertRow();
const labelCell = row.insertCell();
const valueCell = row.insertCell();
labelCell.className = 'py-2 px-4 border-b border-gray-200';
valueCell.className = 'py-2 px-4 border-b border-gray-200';
labelCell.textContent = item.label;
valueCell.textContent = currentValuesMap[item.id];
});
}
// Collect current values from live DOM for PDF
const currentExternalDebtValues = {
externalDebtToGdp: document.getElementById('externalDebtToGdp').value + '%',
shortTermDebtToReserves: document.getElementById('shortTermDebtToReserves').value + '%',
foreignCurrencyDebtRatio: document.getElementById('foreignCurrencyDebtRatio').value + '%',
internationalReservesMonths: document.getElementById('internationalReservesMonths').value + ' months'
};
const externalDebtInputsDef = [
{ id: 'externalDebtToGdp', label: 'External Debt to GDP' },
{ id: 'shortTermDebtToReserves', label: 'Short-term External Debt to Reserves' },
{ id: 'foreignCurrencyDebtRatio', label: 'Foreign Currency Debt to Total Debt' },
{ id: 'internationalReservesMonths', label: 'International Reserves (Months of Imports)' }
];
createInputTable('External Debt & Liquidity Inputs', externalDebtInputsDef, currentExternalDebtValues);
const currentMacroeconomicValues = {
currentAccountBalance: document.getElementById('currentAccountBalance').value + '%',
fiscalDeficit: document.getElementById('fiscalDeficit').value + '%',
inflationRate: document.getElementById('inflationRate').value + '%',
realGdpGrowth: document.getElementById('realGdpGrowth').value + '%'
};
const macroeconomicInputsDef = [
{ id: 'currentAccountBalance', label: 'Current Account Balance (% of GDP)' },
{ id: 'fiscalDeficit', label: 'Fiscal Deficit (% of GDP)' },
{ id: 'inflationRate', label: 'Inflation Rate (%)' },
{ id: 'realGdpGrowth', label: 'Real GDP Growth Rate (%)' }
];
createInputTable('Macroeconomic Health Inputs', macroeconomicInputsDef, currentMacroeconomicValues);
const currentGovernanceGlobalValues = {
politicalStability: document.getElementById('politicalStability').options[document.getElementById('politicalStability').selectedIndex].text,
ruleOfLawCorruption: document.getElementById('ruleOfLawCorruption').options[document.getElementById('ruleOfLawCorruption').selectedIndex].text,
centralBankIndependence: document.getElementById('centralBankIndependence').options[document.getElementById('centralBankIndependence').selectedIndex].text,
globalLiquidity: document.getElementById('globalLiquidity').options[document.getElementById('globalLiquidity').selectedIndex].text,
globalRiskAppetite: document.getElementById('globalRiskAppetite').options[document.getElementById('globalRiskAppetite').selectedIndex].text
};
const governanceGlobalInputsDef = [
{ id: 'politicalStability', label: 'Political Stability' },
{ id: 'ruleOfLawCorruption', label: 'Rule of Law / Corruption Perception' },
{ id: 'centralBankIndependence', label: 'Central Bank Independence' },
{ id: 'globalLiquidity', label: 'Global Liquidity Conditions' },
{ id: 'globalRiskAppetite', label: 'Global Risk Appetite' }
];
createInputTable('Governance & Global Environment Inputs', governanceGlobalInputsDef, currentGovernanceGlobalValues);
// --- Section: AI Analysis & Allocation ---
const analysisResultsSection = document.createElement('div');
analysisResultsSection.className = 'mt-8 p-6 bg-gray-50 rounded-lg shadow-inner';
analysisResultsSection.innerHTML = `
Emerging Market Debt Risk Assessment
Overall Emerging Markets Debt Risk:
Total Risk Score: ${totalDebtRiskScoreSpan.textContent} (Higher score = Higher risk)
Key Contributing Factors:
${contributingFactorsList.innerHTML}
`;
pdfContentDiv.appendChild(analysisResultsSection);
// --- Section: Strategic Recommendations ---
const recommendationsSection = document.createElement('div');
recommendationsSection.className = 'mt-8 p-6 bg-blue-50 rounded-lg shadow-inner text-gray-700';
recommendationsSection.innerHTML = `
Strategic Guidance:
${recommendationsContentList.innerHTML}
`;
pdfContentDiv.appendChild(recommendationsSection);
try {
const canvas = await html2canvas(pdfContentDiv, {
scale: 2, // Increase scale for better resolution in PDF
useCORS: true // Required if you have external images/resources (though none here)
});
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'px',
format: 'a4'
});
const imgWidth = pdf.internal.pageSize.getWidth() - 40; // Subtract margins (20px each side)
const imgHeight = (canvas.height * imgWidth) / canvas.width;
let position = 20; // Initial Y position with top margin
pdf.addImage(imgData, 'PNG', 20, position, imgWidth, imgHeight);
// Handle multi-page PDF for long content
let heightLeft = imgHeight;
heightLeft -= (pdf.internal.pageSize.getHeight() - 40); // Subtract current page usable height
while (heightLeft >= -5) { // Adjusted condition to catch slightly overflowing content
position = heightLeft - imgHeight + 20; // Calculate position for next page
pdf.addPage();
pdf.addImage(imgData, 'PNG', 20, position, imgWidth, imgHeight);
heightLeft -= (pdf.internal.pageSize.getHeight() - 40);
}
pdf.save('AI_EM_Debt_Risk_Report.pdf');
} catch (error) {
console.error("Error generating PDF:", error);
// Provide user feedback without alert()
const messageBox = document.createElement('div');
messageBox.textContent = "Failed to generate PDF. Please try again or check console for details.";
messageBox.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #f8d7da;
color: #721c24;
padding: 15px 25px;
border-radius: 8px;
border: 1px solid #f5c6cb;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
font-family: 'Inter', sans-serif;
`;
document.body.appendChild(messageBox);
setTimeout(() => messageBox.remove(), 5000); // Remove after 5 seconds
} finally {
// Hide loading spinner and re-enable button
pdfSpinner.classList.add('hidden');
downloadPdfBtn.disabled = false;
// Remove the temporary PDF content div from the DOM
if (pdfContentDiv.parentNode) {
pdfContentDiv.parentNode.removeChild(pdfContentDiv);
}
}
}
});