/**
 * RC Report Generator — PR-15 Active Memory Precompute RC
 *
 * 将 RC Checklist 结果转换为可读、可归档、可审计的 Markdown 报告。
 *
 * 纯函数：不读写任何文件、环境变量、数据库或生产路径。
 *
 * 输入：evaluateReleaseCandidate() 的输出
 * 输出：GitHub 友好的 Markdown 字符串
 *
 * @module generate-release-candidate-report
 */

// ─── 检查项标签 ──────────────────────────────────────

const CHECK_LABELS = {
  readiness:       "Readiness Assessment",
  rolloutStage:    "Rollout Stage Policy",
  rollback:         "Rollback Report",
  circuitBreaker:   "Circuit Breaker",
  tests:            "Test Summary",
};

// ─── 检查项详情格式化 ────────────────────────────────

/** @param {string} key @param {object} check @returns {string} */
function formatCheckDetail(key, check) {
  switch (key) {
    case "readiness": {
      const parts = [`status=${check.status}`, `safeToReplace=${check.safeToReplace}`];
      if (check.score != null) parts.push(`score=${check.score}`);
      return parts.join(", ");
    }
    case "rolloutStage": {
      const parts = [`action=${check.action}`, `stage=${check.currentStage}%`];
      if (check.confidence != null) parts.push(`confidence=${check.confidence}`);
      return parts.join(", ");
    }
    case "rollback":
      return `recommendation=${check.recommendation}`;
    case "circuitBreaker":
      return `state=${check.state}`;
    case "tests": {
      const parts = [`total=${check.total}`, `failed=${check.failed}`];
      if (check.regressions != null) parts.push(`regressions=${check.regressions}`);
      return parts.join(", ");
    }
    default:
      return JSON.stringify(check);
  }
}

// ─── 报告生成 ────────────────────────────────────────

/**
 * 生成 RC Report Markdown。
 *
 * @param {object} result — evaluateReleaseCandidate() 的返回值
 * @param {string}  result.status            — "pass" | "warn" | "fail"
 * @param {boolean} result.releaseCandidate  — 是否可进入 RC
 * @param {number}  result.confidence        — 置信度 0-100
 * @param {string[]} result.blockers         — 阻塞项
 * @param {string[]} result.warnings         — 警示项
 * @param {object}  result.checks            — 各检查项详情
 * @param {string}  result.recommendation    — 建议文本
 * @param {object}  [baselineCompare]        — PR-16 baseline 比较结果（可选）
 * @param {string}  baselineCompare.status
 * @param {object[]} baselineCompare.changes
 * @param {string[]} baselineCompare.blockers
 * @param {string[]} baselineCompare.warnings
 * @param {object}  [releaseGate]            — PR-17 release gate 结果（可选）
 * @param {string}  releaseGate.status       — "open" | "closed"
 * @param {boolean} releaseGate.canRelease
 * @param {string[]} releaseGate.blockers
 * @param {string[]} releaseGate.warnings
 * @param {string}  releaseGate.summary
 * @returns {string} Markdown 报告
 */
export function generateReleaseCandidateReport(result, baselineCompare, releaseGate) {
  if (!result || typeof result !== "object") {
    return _emptyReport();
  }

  const {
    status = "unknown",
    releaseCandidate = false,
    confidence = 0,
    blockers = [],
    warnings = [],
    checks = {},
    recommendation = "",
  } = result;

  const lines = [];

  // ── 标题 ──
  lines.push("# Active Memory Release Candidate Report");
  lines.push("");

  // ── Summary ──
  const statusIcon = status === "pass" ? "✅" : status === "warn" ? "⚠️" : "❌";
  const statusLabel = status.toUpperCase();
  const rcLabel = releaseCandidate ? "YES" : "NO";
  const score = typeof confidence === "number" ? Math.round(confidence) : 0;

  lines.push("## Summary");
  lines.push("");
  lines.push(`| Field | Value |`);
  lines.push(`|-------|-------|`);
  lines.push(`| Status | ${statusIcon} **${statusLabel}** |`);
  lines.push(`| Release Candidate | **${rcLabel}** |`);
  lines.push(`| Score | **${score}/100** |`);
  lines.push("");

  // ── Checks ──
  lines.push("## Checks");
  lines.push("");

  const checkEntries = Object.entries(checks);
  if (checkEntries.length > 0) {
    lines.push("| Check | Result | Details |");
    lines.push("|-------|--------|---------|");
    for (const [key, check] of checkEntries) {
      const label = CHECK_LABELS[key] || key;
      const icon = check.pass === true ? "✅" : "❌";
      const detail = formatCheckDetail(key, check);
      lines.push(`| ${icon} ${label} | ${check.pass ? "PASS" : "FAIL"} | ${detail} |`);
    }
  } else {
    lines.push("_No check data available._");
  }
  lines.push("");

  // ── Blockers ──
  lines.push("## Blockers");
  lines.push("");
  if (blockers.length > 0) {
    for (const b of blockers) {
      lines.push(`- ❌ ${b}`);
    }
  } else {
    lines.push("None");
  }
  lines.push("");

  // ── Warnings ──
  lines.push("## Warnings");
  lines.push("");
  if (warnings.length > 0) {
    for (const w of warnings) {
      lines.push(`- ⚠️ ${w}`);
    }
  } else {
    lines.push("None");
  }
  lines.push("");

  // ── Baseline Comparison (PR-16) ──
  lines.push("## Baseline Comparison");
  lines.push("");
  if (baselineCompare && baselineCompare.changes && baselineCompare.changes.length > 0) {
    const { status: bcStatus, changes: bcChanges, blockers: bcBlockers, warnings: bcWarnings } = baselineCompare;
    const bcIcon = bcStatus === "pass" ? "✅" : bcStatus === "warn" ? "⚠️" : "❌";
    lines.push(`Status: ${bcIcon} **${(bcStatus || "unknown").toUpperCase()}**`);
    lines.push("");
    lines.push("| Metric | Baseline | Candidate | Delta | Δ% |");
    lines.push("|--------|----------|-----------|-------|-----|");
    for (const c of bcChanges) {
      const deltaSign = c.delta > 0 ? "+" : "";
      const absPct = Math.abs(c.deltaPercent);
      const pctIcon = absPct > 50 ? "🔴" : absPct > 20 ? "🟡" : "";
      lines.push(`| ${c.label} | ${c.baseline} | ${c.candidate} | ${deltaSign}${c.delta} | ${pctIcon} ${deltaSign}${c.deltaPercent}% |`);
    }
    lines.push("");
    if (bcBlockers && bcBlockers.length > 0) {
      lines.push("**Baseline Blockers:**");
      for (const b of bcBlockers) lines.push(`- ❌ ${b}`);
      lines.push("");
    }
    if (bcWarnings && bcWarnings.length > 0) {
      lines.push("**Baseline Warnings:**");
      for (const w of bcWarnings) lines.push(`- ⚠️ ${w}`);
      lines.push("");
    }
  } else {
    lines.push("_Baseline comparison unavailable._");
    lines.push("");
  }

  // ── Release Gate (PR-17) ──
  lines.push("## Release Gate");
  lines.push("");
  if (releaseGate && typeof releaseGate === "object") {
    const rgIcon = releaseGate.status === "open" ? "🟢" : "🔴";
    const rgDecision = (releaseGate.decision || "UNKNOWN").toUpperCase();
    const rgCanRelease = releaseGate.canRelease ? "YES" : "NO";
    lines.push(`Status: ${rgIcon} **${rgDecision}**`);
    lines.push("");
    lines.push(`Can Release: **${rgCanRelease}**`);
    lines.push("");
    if (releaseGate.summary) {
      lines.push(`Summary: ${releaseGate.summary}`);
      lines.push("");
    }
    if (releaseGate.blockers && releaseGate.blockers.length > 0) {
      lines.push("**Gate Blockers:**");
      for (const b of releaseGate.blockers) lines.push(`- ❌ ${b}`);
      lines.push("");
    }
    if (releaseGate.warnings && releaseGate.warnings.length > 0) {
      lines.push("**Gate Warnings:**");
      for (const w of releaseGate.warnings) lines.push(`- ⚠️ ${w}`);
      lines.push("");
    }
  } else {
    lines.push("_Release gate decision unavailable._");
    lines.push("");
  }

  // ── Recommendation ──
  if (recommendation) {
    const cleanRec = recommendation.replace(/\n/g, "\n  ");
    lines.push("## Recommendation");
    lines.push("");
    lines.push(`> ${cleanRec}`);
    lines.push("");
  }

  // ── Footer ──
  const ts = new Date().toISOString();
  lines.push("---");
  lines.push(`_Generated at ${ts}_`);

  return lines.join("\n") + "\n";
}

// ─── 空报告（invalid input）─────────────────────────

function _emptyReport() {
  const ts = new Date().toISOString();
  return [
    "# Active Memory Release Candidate Report",
    "",
    "## Summary",
    "",
    "| Field | Value |",
    "|-------|-------|",
    "| Status | ❌ **FAIL** |",
    "| Release Candidate | **NO** |",
    "| Score | **0/100** |",
    "",
    "## Checks",
    "",
    "_Invalid or missing input. No check data available._",
    "",
    "## Blockers",
    "",
    "- ❌ Invalid input: cannot evaluate RC condition",
    "",
    "## Warnings",
    "",
    "None",
    "",
    "---",
    `_Generated at ${ts}_`,
    "",
  ].join("\n");
}
