// ---------------------------------------------------------------------------
// ID generation
// ---------------------------------------------------------------------------
/** Generate a simple UUID-like ID for a tech debt item. */
export function generateDebtId() {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).slice(2, 8);
    return `debt-${timestamp}-${random}`;
}
// ---------------------------------------------------------------------------
// Metrics
// ---------------------------------------------------------------------------
/** Compute summary metrics from a list of tech debt items. */
export function computeTechDebtMetrics(items) {
    const open = items.filter((i) => i.status === 'open');
    const resolved = items.filter((i) => i.status === 'resolved');
    const bySeverity = {};
    const byCategory = {};
    for (const item of open) {
        bySeverity[item.severity] = (bySeverity[item.severity] ?? 0) + 1;
        byCategory[item.category] = (byCategory[item.category] ?? 0) + 1;
    }
    return {
        totalItems: items.length,
        openItems: open.length,
        resolvedItems: resolved.length,
        totalOpenHours: open.reduce((acc, i) => acc + i.estimatedHours, 0),
        bySeverity,
        byCategory,
    };
}
// ---------------------------------------------------------------------------
// Forecast
// ---------------------------------------------------------------------------
/** Calculate weekly accumulation rate from historical items. */
function weeklyRate(items) {
    if (items.length === 0) {
        return 0;
    }
    const sorted = [...items].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
    const first = sorted[0];
    const last = sorted[sorted.length - 1];
    /* v8 ignore next 2 */
    if (!first || !last) {
        return 0;
    }
    const spanMs = new Date(last.createdAt).getTime() - new Date(first.createdAt).getTime();
    const spanWeeks = Math.max(spanMs / (1000 * 60 * 60 * 24 * 7), 1);
    return items.length / spanWeeks;
}
/** Forecast tech debt growth given current items and config. */
export function forecastTechDebt(items, config) {
    const open = items.filter((i) => i.status === 'open');
    const currentOpenHours = open.reduce((acc, i) => acc + i.estimatedHours, 0);
    const avgHoursPerItem = open.length > 0 ? currentOpenHours / open.length : 4;
    const weeklyAccumulationRate = weeklyRate(items);
    const weeklyHoursRate = weeklyAccumulationRate * avgHoursPerItem;
    const projectedHoursIn4Weeks = currentOpenHours + weeklyHoursRate * 4;
    const maxHours = config.maxHours ?? null;
    let weeksUntilBudgetExceeded = null;
    if (maxHours !== null && weeklyHoursRate > 0) {
        const remainingCapacity = maxHours - currentOpenHours;
        if (remainingCapacity <= 0) {
            weeksUntilBudgetExceeded = 0;
        }
        else {
            weeksUntilBudgetExceeded = Math.ceil(remainingCapacity / weeklyHoursRate);
        }
    }
    return {
        currentOpenHours,
        weeklyAccumulationRate,
        weeksUntilBudgetExceeded,
        projectedHoursIn4Weeks,
        budgetMaxHours: maxHours,
    };
}
// ---------------------------------------------------------------------------
// HTML report
// ---------------------------------------------------------------------------
/** Generate a simple HTML report of tech debt. */
export function generateTechDebtReport(items, config) {
    const metrics = computeTechDebtMetrics(items);
    const forecast = forecastTechDebt(items, config);
    const open = items.filter((i) => i.status === 'open');
    const severityBadge = (s) => {
        const colors = {
            critical: '#dc2626',
            high: '#ea580c',
            medium: '#d97706',
            low: '#16a34a',
        };
        const color = colors[s] ?? '#6b7280';
        return `<span style="background:${color};color:#fff;padding:2px 6px;border-radius:4px;font-size:12px">${s}</span>`;
    };
    const rows = open
        .map((i) => `
    <tr>
      <td>${i.id}</td>
      <td>${i.description}</td>
      <td>${severityBadge(i.severity)}</td>
      <td>${i.category}</td>
      <td>${String(i.estimatedHours)}h</td>
      <td>${i.specId ?? '-'}</td>
      <td>${i.createdAt.slice(0, 10)}</td>
    </tr>`)
        .join('');
    return `<!DOCTYPE html>
<html>
<head><title>Tech Debt Report</title>
<style>body{font-family:sans-serif;padding:20px}table{border-collapse:collapse;width:100%}
th,td{border:1px solid #ddd;padding:8px;text-align:left}th{background:#f3f4f6}</style>
</head>
<body>
<h1>Tech Debt Report</h1>
<section>
  <h2>Summary</h2>
  <p>Open items: <strong>${String(metrics.openItems)}</strong> |
     Total open hours: <strong>${String(metrics.totalOpenHours)}h</strong> |
     Resolved: <strong>${String(metrics.resolvedItems)}</strong></p>
  <p>Weekly accumulation rate: <strong>${forecast.weeklyAccumulationRate.toFixed(1)} items/week</strong></p>
  ${forecast.weeksUntilBudgetExceeded !== null ? `<p>Budget exceeded in: <strong>${String(forecast.weeksUntilBudgetExceeded)} weeks</strong></p>` : ''}
  ${forecast.budgetMaxHours !== null ? `<p>Budget max hours: <strong>${String(forecast.budgetMaxHours)}h</strong></p>` : ''}
</section>
<section>
  <h2>Open Debt Items</h2>
  <table>
    <tr><th>ID</th><th>Description</th><th>Severity</th><th>Category</th><th>Est. Hours</th><th>Spec</th><th>Created</th></tr>
    ${rows || '<tr><td colspan="7">No open debt items.</td></tr>'}
  </table>
</section>
</body>
</html>`;
}
// ---------------------------------------------------------------------------
// Filter helpers
// ---------------------------------------------------------------------------
/** Filter tech debt items by status and/or severity and/or category. */
export function filterDebtItems(items, status, severity, category) {
    let result = items;
    if (status && status !== 'all') {
        result = result.filter((i) => i.status === status);
    }
    if (severity) {
        result = result.filter((i) => i.severity === severity);
    }
    if (category) {
        result = result.filter((i) => i.category === category);
    }
    return result;
}
//# sourceMappingURL=tech-debt-manager.js.map