import { buildNavbar } from './portal-navbar.js';
import { getPortalThemeCSS } from './portal-theme.js';
import { buildRiskMatrixSvg } from './risk-matrix-svg.js';
import { buildRiskGaugeSvg } from './risk-gauge-svg.js';
function escapeHtml(s) {
    return s
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}
const STATUS_BADGE = {
    identified: 'planu-badge-muted',
    mitigating: 'planu-badge-info',
    mitigated: 'planu-badge-success',
    accepted: 'planu-badge-warning',
    materialized: 'planu-badge-danger',
};
function statusBadge(status) {
    const cls = STATUS_BADGE[status];
    return `<span class="planu-badge ${cls}">${escapeHtml(status)}</span>`;
}
function categoryBadge(cat) {
    const colors = {
        technical: 'planu-badge-info',
        security: 'planu-badge-danger',
        integration: 'planu-badge-warning',
        dependency: 'planu-badge-muted',
        organizational: 'planu-badge-muted',
        data: 'planu-badge-success',
    };
    return `<span class="planu-badge ${colors[cat]}">${escapeHtml(cat)}</span>`;
}
function buildRiskTable(allRisks, specMap) {
    if (allRisks.length === 0) {
        return `<p class="empty-message">No risks registered yet.</p>`;
    }
    const rows = allRisks
        .map((r) => {
        const specTitle = specMap.get(r.specId) ?? r.specId;
        return `<tr>
        <td>${escapeHtml(r.id)}</td>
        <td title="${escapeHtml(r.specId)}">${escapeHtml(specTitle)}</td>
        <td>${escapeHtml(r.description)}</td>
        <td>${categoryBadge(r.category)}</td>
        <td class="num">${r.probability}%</td>
        <td class="num">$${r.impactUsd.toLocaleString('en-US')}</td>
        <td class="num">${r.impactDays}d</td>
        <td>${escapeHtml(r.mitigationPlan || '—')}</td>
        <td>${escapeHtml(r.owner || '—')}</td>
        <td>${statusBadge(r.status)}</td>
      </tr>`;
    })
        .join('\n');
    return `<div class="table-wrap">
    <table class="risk-table sortable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Spec</th>
          <th>Description</th>
          <th>Category</th>
          <th class="sortable-col">Probability</th>
          <th class="sortable-col">Impact $</th>
          <th class="sortable-col">Impact Days</th>
          <th>Mitigation</th>
          <th>Owner</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        ${rows}
      </tbody>
    </table>
  </div>`;
}
function buildCoverageSection(allRisks) {
    if (allRisks.length === 0) {
        return '';
    }
    const total = allRisks.length;
    const withPlan = allRisks.filter((r) => r.mitigationPlan && r.mitigationPlan.trim().length > 0).length;
    const mitigated = allRisks.filter((r) => r.status === 'mitigated').length;
    const noOwner = allRisks.filter((r) => !r.owner || r.owner.trim() === '').length;
    const planPct = Math.round((withPlan / total) * 100);
    const mitigatedPct = Math.round((mitigated / total) * 100);
    const warning = noOwner > 0
        ? `<div class="coverage-warning">⚠️ <strong>${noOwner}</strong> risk${noOwner > 1 ? 's' : ''} without an assigned owner.</div>`
        : '';
    return `<section class="planu-card section-card">
    <h2>Mitigation Coverage</h2>
    <div class="coverage-grid">
      <div class="coverage-item">
        <span class="coverage-pct">${planPct}%</span>
        <span class="coverage-label">With Mitigation Plan</span>
      </div>
      <div class="coverage-item">
        <span class="coverage-pct coverage-green">${mitigatedPct}%</span>
        <span class="coverage-label">Mitigated</span>
      </div>
      <div class="coverage-item">
        <span class="coverage-pct coverage-red">${noOwner}</span>
        <span class="coverage-label">Without Owner</span>
      </div>
    </div>
    ${warning}
  </section>`;
}
function buildScoreCard(registers, allRisks) {
    const avgScore = registers.length > 0
        ? Math.round(registers.reduce((s, r) => s + r.aggregateRiskScore, 0) / registers.length)
        : 0;
    const highCount = allRisks.filter((r) => r.probability >= 60 && r.impactUsd >= 5000).length;
    const criticalCount = allRisks.filter((r) => r.probability >= 80 && r.impactUsd >= 20000).length;
    const gaugeSvg = buildRiskGaugeSvg(avgScore);
    return `<section class="planu-card section-card score-card">
    <h2>Risk Score</h2>
    <div class="score-layout">
      <div class="gauge-wrap">${gaugeSvg}</div>
      <div class="score-stats">
        <div class="stat-item">
          <span class="stat-num">${allRisks.length}</span>
          <span class="stat-label">Total Risks</span>
        </div>
        <div class="stat-item stat-warn">
          <span class="stat-num">${highCount}</span>
          <span class="stat-label">High Priority</span>
        </div>
        <div class="stat-item stat-danger">
          <span class="stat-num">${criticalCount}</span>
          <span class="stat-label">Critical</span>
        </div>
        <div class="stat-item">
          <span class="stat-num">${registers.length}</span>
          <span class="stat-label">Specs with Risks</span>
        </div>
      </div>
    </div>
  </section>`;
}
function buildPageCSS() {
    return `
  body { font-family: system-ui, sans-serif; margin: 0; padding: 0 16px 48px; background: var(--planu-bg); color: var(--planu-text); }
  .page-title { font-size: 1.6rem; font-weight: 700; margin: 0 0 6px; }
  .page-subtitle { color: #6b7280; margin: 0 0 24px; font-size: 0.95rem; }
  .section-card { margin-bottom: 24px; }
  h2 { font-size: 1.1rem; font-weight: 600; margin: 0 0 16px; color: var(--planu-primary); }
  .matrix-wrap { overflow-x: auto; }
  .matrix-wrap svg { max-width: 100%; height: auto; }
  .table-wrap { overflow-x: auto; }
  .risk-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
  .risk-table th { background: #f3f4f6; text-align: left; padding: 8px 10px; font-weight: 600; white-space: nowrap; border-bottom: 2px solid var(--planu-border); }
  .risk-table td { padding: 8px 10px; border-bottom: 1px solid var(--planu-border); vertical-align: top; }
  .risk-table tr:hover td { background: #f9fafb; }
  .risk-table .num { text-align: right; white-space: nowrap; }
  .score-layout { display: flex; align-items: flex-start; gap: 24px; flex-wrap: wrap; }
  .gauge-wrap { width: 200px; flex-shrink: 0; }
  .gauge-wrap svg { width: 100%; height: auto; }
  .score-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; flex: 1; }
  .stat-item { text-align: center; padding: 12px; background: #f9fafb; border-radius: 8px; }
  .stat-num { display: block; font-size: 1.8rem; font-weight: 700; color: var(--planu-primary); }
  .stat-warn .stat-num { color: var(--planu-warning); }
  .stat-danger .stat-num { color: var(--planu-danger); }
  .stat-label { font-size: 0.78rem; color: #6b7280; }
  .coverage-grid { display: flex; gap: 24px; flex-wrap: wrap; }
  .coverage-item { text-align: center; min-width: 100px; }
  .coverage-pct { display: block; font-size: 2rem; font-weight: 700; color: var(--planu-primary); }
  .coverage-green { color: var(--planu-success); }
  .coverage-red { color: var(--planu-danger); }
  .coverage-label { font-size: 0.82rem; color: #6b7280; }
  .coverage-warning { margin-top: 12px; padding: 10px 14px; background: #fef3c7; border-radius: 8px; font-size: 0.88rem; color: #92400e; }
  .empty-state { text-align: center; padding: 48px 24px; color: #6b7280; }
  .empty-state h3 { font-size: 1.2rem; margin-bottom: 8px; }
  .empty-message { color: #9ca3af; font-style: italic; }`;
}
/**
 * Generate the risks.html portal page.
 */
export function generateRiskPage(risks, specs) {
    const specMap = new Map(specs.map((s) => [s.id, s.title]));
    const allRisks = risks.flatMap((r) => r.risks);
    const navbar = buildNavbar('risks', '');
    const themeCSS = getPortalThemeCSS();
    const pageCSS = buildPageCSS();
    const matrixSvg = buildRiskMatrixSvg(allRisks);
    const matrixSection = allRisks.length > 0
        ? `<section class="planu-card section-card">
    <h2>Risk Matrix</h2>
    <div class="matrix-wrap">${matrixSvg}</div>
  </section>`
        : '';
    const bodyContent = allRisks.length === 0
        ? `<div class="empty-state"><h3>No risk data available</h3><p>Use <code>estimate</code> with risk analysis to populate this page.</p></div>`
        : `${buildScoreCard(risks, allRisks)}
  ${matrixSection}
  <section class="planu-card section-card">
    <h2>Risk Registry</h2>
    ${buildRiskTable(allRisks, specMap)}
  </section>
  ${buildCoverageSection(allRisks)}`;
    return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Risks — Planu Portal</title>
  <style>${themeCSS}${pageCSS}</style>
</head>
<body>
  ${navbar}
  <main>
    <h1 class="page-title">⚠️ Risk Register</h1>
    <p class="page-subtitle">Risk matrix, registry, and mitigation coverage across all specs.</p>
    ${bodyContent}
  </main>
</body>
</html>`;
}
//# sourceMappingURL=risk-page.js.map