const IMPACT_LEVELS = ['low', 'medium', 'high', 'very_high', 'critical'];
const PROB_LEVELS = [20, 40, 60, 80, 100];
const CATEGORY_COLORS = {
    technical: '#3b82f6',
    security: '#ef4444',
    integration: '#f97316',
    dependency: '#8b5cf6',
    organizational: '#6b7280',
    data: '#10b981',
};
const QUADRANT_COLORS = [
    // Row 0 (prob 80-100) high prob
    ['#fef3c7', '#fde68a', '#fcd34d', '#f87171', '#ef4444'],
    // Row 1 (prob 60-80)
    ['#d1fae5', '#fef3c7', '#fde68a', '#fcd34d', '#f87171'],
    // Row 2 (prob 40-60)
    ['#d1fae5', '#d1fae5', '#fef3c7', '#fde68a', '#fcd34d'],
    // Row 3 (prob 20-40)
    ['#d1fae5', '#d1fae5', '#d1fae5', '#fef3c7', '#fde68a'],
    // Row 4 (prob 0-20) low prob
    ['#d1fae5', '#d1fae5', '#d1fae5', '#d1fae5', '#fef3c7'],
];
const CELL = 60;
const PADDING = 40;
const LABEL_PAD = 14;
const GRID_W = CELL * 5;
const GRID_H = CELL * 5;
const SVG_W = GRID_W + PADDING + LABEL_PAD;
const SVG_H = GRID_H + PADDING + LABEL_PAD;
function impactIndex(risk) {
    // Map impactUsd ranges to 0-4
    if (risk.impactUsd < 1000) {
        return 0;
    }
    if (risk.impactUsd < 5000) {
        return 1;
    }
    if (risk.impactUsd < 20000) {
        return 2;
    }
    if (risk.impactUsd < 50000) {
        return 3;
    }
    return 4;
}
function probIndex(risk) {
    const p = risk.probability;
    if (p <= 20) {
        return 4;
    } // row 4 = lowest
    if (p <= 40) {
        return 3;
    }
    if (p <= 60) {
        return 2;
    }
    if (p <= 80) {
        return 1;
    }
    return 0;
}
function circleSizeFromUsd(usd) {
    if (usd < 1000) {
        return 8;
    }
    if (usd < 5000) {
        return 12;
    }
    if (usd < 20000) {
        return 16;
    }
    if (usd < 50000) {
        return 20;
    }
    return 24;
}
function escapeHtml(s) {
    return s
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}
function buildGridCells() {
    const cells = [];
    for (let row = 0; row < 5; row++) {
        for (let col = 0; col < 5; col++) {
            const x = PADDING + col * CELL;
            const y = LABEL_PAD + row * CELL;
            cells.push(`<rect x="${x}" y="${y}" width="${CELL}" height="${CELL}" fill="${QUADRANT_COLORS[row]?.[col] ?? '#d1fae5'}" stroke="#e5e7eb" stroke-width="1"/>`);
        }
    }
    return cells.join('\n  ');
}
function buildAxisLabels() {
    const parts = [];
    // X-axis (Impact) labels
    const impactLabels = ['Low', 'Med', 'High', 'V.High', 'Crit'];
    for (let i = 0; i < 5; i++) {
        const x = PADDING + i * CELL + CELL / 2;
        const y = LABEL_PAD + GRID_H + 14;
        parts.push(`<text x="${x}" y="${y}" text-anchor="middle" font-size="10" fill="#6b7280">${impactLabels[i]}</text>`);
    }
    // X-axis title
    parts.push(`<text x="${PADDING + GRID_W / 2}" y="${SVG_H - 2}" text-anchor="middle" font-size="11" font-weight="600" fill="#374151">Impact</text>`);
    // Y-axis (Probability) labels
    const probLabels = ['80-100%', '60-80%', '40-60%', '20-40%', '0-20%'];
    for (let i = 0; i < 5; i++) {
        const y = LABEL_PAD + i * CELL + CELL / 2 + 4;
        parts.push(`<text x="${PADDING - 4}" y="${y}" text-anchor="end" font-size="10" fill="#6b7280">${probLabels[i]}</text>`);
    }
    // Y-axis title (rotated)
    const cx = 10;
    const cy = LABEL_PAD + GRID_H / 2;
    parts.push(`<text x="${cx}" y="${cy}" text-anchor="middle" font-size="11" font-weight="600" fill="#374151" transform="rotate(-90,${cx},${cy})">Probability</text>`);
    return parts.join('\n  ');
}
function buildRiskDots(risks) {
    // Group risks in same cell to offset them
    const cellMap = new Map();
    for (const r of risks) {
        const key = `${probIndex(r)},${impactIndex(r)}`;
        const arr = cellMap.get(key) ?? [];
        arr.push(r);
        cellMap.set(key, arr);
    }
    const dots = [];
    for (const [key, cellRisks] of cellMap) {
        const parts = key.split(',').map(Number);
        const row = parts[0] ?? 0;
        const col = parts[1] ?? 0;
        const cx = PADDING + col * CELL + CELL / 2;
        const cy = LABEL_PAD + row * CELL + CELL / 2;
        cellRisks.forEach((r, idx) => {
            const offset = (idx - (cellRisks.length - 1) / 2) * 10;
            const rx = cx + (cellRisks.length > 1 ? offset : 0);
            const size = circleSizeFromUsd(r.impactUsd);
            const color = CATEGORY_COLORS[r.category];
            const label = escapeHtml(r.id);
            dots.push(`<circle cx="${rx}" cy="${cy}" r="${size / 2}" fill="${color}" fill-opacity="0.85" stroke="white" stroke-width="1.5">` +
                `<title>${label}: ${escapeHtml(r.description)} ($${r.impactUsd.toLocaleString()})</title>` +
                `</circle>`);
        });
    }
    return dots.join('\n  ');
}
function buildLegend(risks) {
    const categories = [...new Set(risks.map((r) => r.category))];
    const parts = [];
    const startY = LABEL_PAD + 4;
    const startX = PADDING + GRID_W + 10;
    if (startX + 90 > SVG_W + 110) {
        return '';
    } // no room
    categories.forEach((cat, i) => {
        const y = startY + i * 18;
        const color = CATEGORY_COLORS[cat];
        parts.push(`<circle cx="${startX + 6}" cy="${y}" r="5" fill="${color}"/>`);
        parts.push(`<text x="${startX + 14}" y="${y + 4}" font-size="10" fill="#374151">${escapeHtml(cat)}</text>`);
    });
    return parts.join('\n  ');
}
/**
 * Build a 5x5 risk matrix SVG.
 * Returns empty string when risks array is empty.
 */
export function buildRiskMatrixSvg(risks) {
    if (risks.length === 0) {
        return '';
    }
    const legendWidth = 90;
    const totalW = SVG_W + legendWidth;
    return `<svg viewBox="0 0 ${totalW} ${SVG_H}" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Risk Matrix">
  ${buildGridCells()}
  ${buildAxisLabels()}
  ${buildRiskDots(risks)}
  ${buildLegend(risks)}
</svg>`;
}
export { IMPACT_LEVELS, PROB_LEVELS, CATEGORY_COLORS };
//# sourceMappingURL=risk-matrix-svg.js.map