/**
 * Unified report generator for config-audit.
 * Produces markdown reports from posture, drift, and plugin health results.
 * Template strings are embedded in JS — no separate .md files to parse.
 * Zero external dependencies.
 */

const MAX_FINDINGS_PER_SCANNER = 10;
const MAX_REPORT_LINES = 500;

/**
 * Generate a posture report in markdown.
 * @param {object} postureResult - Output from runPosture()
 * @returns {string}
 */
export function generatePostureReport(postureResult) {
  const {
    areas, overallGrade, scannerEnvelope,
  } = postureResult;
  const opportunityCount = postureResult.opportunityCount ?? 0;

  // Quality areas only (exclude Feature Coverage)
  const qualityAreas = areas.filter(a => a.name !== 'Feature Coverage');
  const avgScore = qualityAreas.length > 0
    ? Math.round(qualityAreas.reduce((s, a) => s + a.score, 0) / qualityAreas.length)
    : 0;

  const lines = [];
  const ts = scannerEnvelope?.meta?.timestamp || new Date().toISOString();
  const target = scannerEnvelope?.meta?.target || 'unknown';

  lines.push('## Health Assessment');
  lines.push('');
  lines.push(`> **Date:** ${ts.split('T')[0]}  `);
  lines.push(`> **Target:** \`${target}\`  `);
  lines.push('');

  // Score summary
  lines.push('### Score Summary');
  lines.push('');
  lines.push('| Metric | Value |');
  lines.push('|--------|-------|');
  lines.push(`| Health Grade | **${overallGrade}** (${avgScore}/100) |`);
  lines.push(`| Areas Scanned | ${qualityAreas.length} |`);
  if (opportunityCount > 0) {
    lines.push(`| Opportunities | ${opportunityCount} features available |`);
  }
  lines.push('');

  // Area breakdown
  lines.push('### Area Breakdown');
  lines.push('');
  lines.push('| Area | Grade | Score | Findings |');
  lines.push('|------|-------|-------|----------|');
  for (const a of qualityAreas) {
    lines.push(`| ${a.name} | ${a.grade} | ${a.score} | ${a.findingCount} |`);
  }
  lines.push('');

  // Opportunities pointer (replaces Top Actions)
  if (opportunityCount > 0) {
    lines.push(`> Run \`/config-audit feature-gap\` for ${opportunityCount} context-aware recommendations.`);
    lines.push('');
  }

  // Findings per scanner (collapsed)
  if (scannerEnvelope?.scanners) {
    lines.push('### Findings by Scanner');
    lines.push('');
    for (const sr of scannerEnvelope.scanners) {
      if (sr.findings.length === 0) continue;
      lines.push(`<details>`);
      lines.push(`<summary>${sr.scanner} — ${sr.findings.length} finding(s)</summary>`);
      lines.push('');
      const show = sr.findings.slice(0, MAX_FINDINGS_PER_SCANNER);
      for (const f of show) {
        lines.push(`- \`[${f.severity}]\` ${f.title}${f.file ? ` (${f.file})` : ''}`);
      }
      if (sr.findings.length > MAX_FINDINGS_PER_SCANNER) {
        lines.push(`- _...and ${sr.findings.length - MAX_FINDINGS_PER_SCANNER} more_`);
      }
      lines.push('');
      lines.push('</details>');
      lines.push('');
    }
  }

  return lines.join('\n');
}

/**
 * Generate a drift report in markdown.
 * @param {object} diffResult - Output from diffEnvelopes()
 * @param {string} baselineName - Name of baseline used
 * @returns {string}
 */
export function generateDriftReport(diffResult, baselineName) {
  const lines = [];
  const { summary, scoreChange, newFindings, resolvedFindings, areaChanges } = diffResult;

  const trendIcon = summary.trend === 'improving' ? '&#x2191;'
    : summary.trend === 'degrading' ? '&#x2193;' : '&#x2192;';
  const trendLabel = summary.trend.charAt(0).toUpperCase() + summary.trend.slice(1);

  lines.push('## Drift Report');
  lines.push('');
  lines.push(`> **Baseline:** \`${baselineName}\`  `);
  lines.push(`> **Trend:** ${trendIcon} ${trendLabel}  `);
  lines.push('');

  // Score delta
  const sc = scoreChange;
  const deltaSign = sc.delta > 0 ? '+' : '';
  lines.push('### Score Change');
  lines.push('');
  lines.push(`**${sc.before.grade}** (${sc.before.score}) ${trendIcon} **${sc.after.grade}** (${sc.after.score}) — ${deltaSign}${sc.delta} points`);
  lines.push('');

  // New findings
  if (newFindings.length > 0) {
    lines.push('### New Findings');
    lines.push('');
    lines.push('| Severity | Title | File |');
    lines.push('|----------|-------|------|');
    for (const f of newFindings.slice(0, 20)) {
      lines.push(`| \`${f.severity}\` | ${f.title} | ${f.file || '-'} |`);
    }
    if (newFindings.length > 20) {
      lines.push(`| | _...and ${newFindings.length - 20} more_ | |`);
    }
    lines.push('');
  }

  // Resolved findings
  if (resolvedFindings.length > 0) {
    lines.push('### Resolved Findings');
    lines.push('');
    lines.push('| Severity | Title |');
    lines.push('|----------|-------|');
    for (const f of resolvedFindings.slice(0, 20)) {
      lines.push(`| \`${f.severity}\` | ${f.title} |`);
    }
    if (resolvedFindings.length > 20) {
      lines.push(`| | _...and ${resolvedFindings.length - 20} more_ |`);
    }
    lines.push('');
  }

  // Area changes
  const changed = (areaChanges || []).filter(a => a.delta !== 0);
  if (changed.length > 0) {
    lines.push('### Area Changes');
    lines.push('');
    lines.push('| Area | Before | After | Delta |');
    lines.push('|------|--------|-------|-------|');
    for (const a of changed) {
      const sign = a.delta > 0 ? '+' : '';
      lines.push(`| ${a.name} | ${a.before.grade} (${a.before.score}) | ${a.after.grade} (${a.after.score}) | ${sign}${a.delta} |`);
    }
    lines.push('');
  }

  return lines.join('\n');
}

/**
 * Generate a plugin health report in markdown.
 * @param {object} scanResult - Scanner result from plugin-health-scanner scan()
 * @param {Array<{ name: string, findings: object[], commandCount: number, agentCount: number }>} pluginResults
 * @returns {string}
 */
export function generatePluginHealthReport(scanResult, pluginResults) {
  const lines = [];

  lines.push('## Plugin Health');
  lines.push('');

  if (!pluginResults || pluginResults.length === 0) {
    lines.push('_No plugins found._');
    lines.push('');
    return lines.join('\n');
  }

  // Plugin summary table
  lines.push('| Plugin | Grade | Score | Commands | Agents | Issues |');
  lines.push('|--------|-------|-------|----------|--------|--------|');
  for (const p of pluginResults) {
    const issueCount = p.findings.length;
    const score = Math.max(0, 100 - issueCount * 10);
    const grade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 60 ? 'C' : score >= 40 ? 'D' : 'F';
    lines.push(`| ${p.name} | ${grade} | ${score} | ${p.commandCount} | ${p.agentCount} | ${issueCount} |`);
  }
  lines.push('');

  // Per-plugin findings
  for (const p of pluginResults) {
    if (p.findings.length === 0) continue;
    lines.push(`<details>`);
    lines.push(`<summary>${p.name} — ${p.findings.length} issue(s)</summary>`);
    lines.push('');
    for (const f of p.findings.slice(0, MAX_FINDINGS_PER_SCANNER)) {
      lines.push(`- \`[${f.severity}]\` ${f.title}`);
    }
    lines.push('');
    lines.push('</details>');
    lines.push('');
  }

  // Cross-plugin issues (from scanResult.findings where title contains "Cross-plugin")
  const crossPlugin = (scanResult?.findings || []).filter(f => f.title.includes('Cross-plugin'));
  if (crossPlugin.length > 0) {
    lines.push('### Cross-Plugin Issues');
    lines.push('');
    for (const f of crossPlugin) {
      lines.push(`- \`[${f.severity}]\` ${f.title}: ${f.description}`);
    }
    lines.push('');
  }

  return lines.join('\n');
}

/**
 * Generate a unified full report combining all sections.
 * Each input is optional (null = skip that section).
 * @param {object|null} postureResult - From runPosture()
 * @param {object|null} driftResult - { diff, baselineName } from diffEnvelopes()
 * @param {object|null} pluginHealthResult - { scanResult, pluginResults } from plugin-health-scanner
 * @returns {string}
 */
export function generateFullReport(postureResult, driftResult, pluginHealthResult) {
  const lines = [];

  lines.push('# Config-Audit Report');
  lines.push('');
  lines.push(`_Generated: ${new Date().toISOString().split('T')[0]}_`);
  lines.push('');
  lines.push('---');
  lines.push('');

  if (postureResult) {
    lines.push(generatePostureReport(postureResult));
    lines.push('---');
    lines.push('');
  }

  if (driftResult) {
    lines.push(generateDriftReport(driftResult.diff, driftResult.baselineName));
    lines.push('---');
    lines.push('');
  }

  if (pluginHealthResult) {
    lines.push(generatePluginHealthReport(
      pluginHealthResult.scanResult,
      pluginHealthResult.pluginResults,
    ));
    lines.push('---');
    lines.push('');
  }

  if (!postureResult && !driftResult && !pluginHealthResult) {
    lines.push('_No data provided for report._');
    lines.push('');
  }

  // Truncate if over limit
  const result = lines.join('\n');
  const resultLines = result.split('\n');
  if (resultLines.length > MAX_REPORT_LINES) {
    const truncated = resultLines.slice(0, MAX_REPORT_LINES);
    truncated.push('');
    truncated.push(`_Report truncated at ${MAX_REPORT_LINES} lines. Run individual reports for full details._`);
    return truncated.join('\n');
  }

  return result;
}
