/**
 * PDF Exporter
 * ─────────────
 * Generates a branded PDF from a ReportDocument using the HTML→PDF
 * approach via Puppeteer (already available for headless crawl).
 *
 * Renders a styled HTML document and prints it to PDF.
 * This avoids a separate PDF layout library — the same
 * narrative report styling applies.
 */

import type { ReportDocument, ReportBlock, ReportMeta } from "./report-export";

// ─── Generate PDF Buffer ────────────────────────────────────────────────────

export async function generatePdf(doc: ReportDocument): Promise<Buffer> {
  const html = renderToHtml(doc);

  // Use Puppeteer to convert HTML → PDF
  const chromium = (await import("@sparticuz/chromium")).default;
  const puppeteer = await import("puppeteer-core");

  const browser = await puppeteer.default.launch({
    args: [...chromium.args, "--no-sandbox", "--disable-gpu"],
    defaultViewport: { width: 1280, height: 720 },
    executablePath: await chromium.executablePath(),
    headless: true,
  });

  try {
    const page = await browser.newPage();
    await page.setContent(html, { waitUntil: "load" });
    await page.waitForNetworkIdle({ idleTime: 500 }).catch(() => {});

    const pdf = await page.pdf({
      format: "A4",
      margin: { top: "60px", right: "50px", bottom: "60px", left: "50px" },
      printBackground: true,
      displayHeaderFooter: true,
      headerTemplate: `<div style="font-size:8px;color:#94a3b8;width:100%;text-align:right;padding-right:50px;font-family:system-ui,sans-serif;">${doc.meta.appBrand} · ${doc.meta.clientName}</div>`,
      footerTemplate: `<div style="font-size:8px;color:#94a3b8;width:100%;text-align:center;font-family:system-ui,sans-serif;">${doc.meta.appBrand} Analysis Report · ${doc.meta.reportDate} · Page <span class="pageNumber"></span></div>`,
    });

    return Buffer.from(pdf);
  } finally {
    await browser.close();
  }
}

// ─── HTML Renderer ──────────────────────────────────────────────────────────

function renderToHtml(doc: ReportDocument): string {
  const m = doc.meta;
  const bodyHtml = doc.blocks.map(renderBlock).join("\n");

  return `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; color: #334155; line-height: 1.6; padding: 40px 0; }
  .container { max-width: 680px; margin: 0 auto; }

  /* Header */
  .report-header { margin-bottom: 40px; padding-bottom: 24px; border-bottom: 2px solid #e2e8f0; }
  .brand-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.15em; color: #EF4444; }
  .report-title { font-size: 24px; font-weight: 700; color: #0f172a; margin-top: 8px; }
  .report-subtitle { font-size: 13px; color: #94a3b8; margin-top: 4px; }

  /* Headings */
  h2 { font-size: 17px; font-weight: 700; color: #0f172a; margin-top: 32px; margin-bottom: 14px; padding-bottom: 6px; border-bottom: 1px solid #f1f5f9; }
  h3 { font-size: 14px; font-weight: 700; color: #334155; margin-top: 20px; margin-bottom: 8px; }

  /* Text */
  p { font-size: 13px; color: #475569; margin-bottom: 10px; }
  .summary-box { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 20px; margin-bottom: 16px; }
  .summary-box p { font-size: 14px; color: #334155; line-height: 1.8; margin-bottom: 8px; }

  /* Callouts */
  .callout { padding: 14px 16px; border-radius: 8px; margin-bottom: 10px; border-left: 4px solid; }
  .callout-critical { background: #fef2f2; border-color: #dc2626; }
  .callout-warning { background: #fffbeb; border-color: #d97706; }
  .callout-info { background: #eff6ff; border-color: #2563eb; }
  .callout-title { font-size: 12px; font-weight: 700; margin-bottom: 2px; }
  .callout-body { font-size: 12px; opacity: 0.8; }

  /* Metrics */
  .metric { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid #f1f5f9; }
  .metric-label { font-size: 13px; font-weight: 600; color: #334155; }
  .metric-source { font-size: 10px; color: #94a3b8; }
  .metric-value { font-size: 15px; font-weight: 700; color: #0f172a; text-align: right; }
  .metric-change { font-size: 11px; }
  .change-up { color: #16a34a; }
  .change-down { color: #dc2626; }
  .change-flat { color: #94a3b8; }

  /* Findings */
  .finding { margin-bottom: 16px; }
  .finding-header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
  .finding-num { font-weight: 700; font-size: 13px; }
  .badge { font-size: 9px; font-weight: 700; text-transform: uppercase; padding: 2px 6px; border-radius: 4px; }
  .badge-critical { background: #fef2f2; color: #dc2626; }
  .badge-high { background: #fff7ed; color: #ea580c; }
  .badge-medium { background: #fffbeb; color: #d97706; }
  .badge-low { background: #eff6ff; color: #2563eb; }
  .finding-desc { font-size: 12px; color: #64748b; margin-left: 24px; }
  .finding-evidence { font-size: 11px; color: #94a3b8; font-family: monospace; background: #f8fafc; padding: 6px 10px; border-radius: 6px; margin: 6px 0 6px 24px; }
  .finding-impact { font-size: 11px; color: #d97706; font-style: italic; margin-left: 24px; }

  /* Predictions */
  .prediction { padding: 12px 0; border-bottom: 1px solid #f1f5f9; }
  .prediction-metric { font-weight: 600; font-size: 13px; }
  .prediction-value { font-size: 18px; font-weight: 700; color: #0f172a; }
  .prediction-detail { font-size: 11px; color: #94a3b8; }
  .prediction-caveat { font-size: 11px; color: #d97706; font-style: italic; margin-top: 4px; }

  /* Recommendations */
  .rec { margin-bottom: 14px; }
  .rec-header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
  .rec-desc { font-size: 12px; color: #64748b; margin-left: 24px; }
  .rec-impact { font-size: 11px; color: #16a34a; margin-left: 24px; margin-top: 4px; }

  /* Sources */
  .source { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid #f8fafc; font-size: 12px; }
  .source-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 6px; }
  .source-available { background: #16a34a; }
  .source-missing { background: #cbd5e1; }

  /* Footer */
  .report-footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #e2e8f0; text-align: center; }
  .footer-brand { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.15em; color: #cbd5e1; }
  .footer-detail { font-size: 11px; color: #94a3b8; margin-top: 4px; }

  .divider { border-bottom: 1px solid #e2e8f0; margin: 24px 0; }
  .spacer { height: 16px; }
</style>
</head>
<body>
<div class="container">

  <div class="report-header">
    <div class="brand-label">${esc(m.appBrand)} · Analysis Report</div>
    <div class="report-title">${esc(m.reportTitle)}</div>
    <div class="report-subtitle">${esc(m.clientName)} · ${esc(m.clientDomain)} · ${esc(m.reportDate)}</div>
  </div>

  ${bodyHtml}

  <div class="report-footer">
    <div class="footer-brand">${esc(m.appBrand)}</div>
    <div class="footer-detail">Generated ${esc(m.reportDate)} by ${esc(m.generatedBy)}</div>
    <div class="footer-detail">${esc(m.clientName)} · ${esc(m.clientDomain)}</div>
  </div>

</div>
</body>
</html>`;
}

function renderBlock(block: ReportBlock): string {
  switch (block.type) {
    case "heading":
      return `<h${block.level}>${esc(block.text)}</h${block.level}>`;

    case "paragraph":
      return `<p>${esc(block.text)}</p>`;

    case "callout":
      return `<div class="callout callout-${block.severity}"><div class="callout-title">${esc(block.severity.toUpperCase())}: ${esc(block.title)}</div><div class="callout-body">${esc(block.body)}</div></div>`;

    case "metric_row":
      return `<div class="metric"><div><div class="metric-label">${esc(block.label)}</div><div class="metric-source">${esc(block.source)}</div></div><div><div class="metric-value">${esc(block.value)}</div>${block.change ? `<div class="metric-change change-${block.changeDirection ?? "flat"}">${esc(block.change)}</div>` : ""}</div></div>`;

    case "finding":
      return `<div class="finding"><div class="finding-header"><span class="finding-num">${block.index}.</span><span class="badge badge-${block.severity}">${esc(block.severity)}</span><strong>${esc(block.title)}</strong>${block.citations ? ` <span style="color:#EF4444;font-size:10px;">${esc(block.citations)}</span>` : ""}</div><div class="finding-desc">${esc(block.description)}</div>${block.evidence ? `<div class="finding-evidence">${esc(block.evidence)}</div>` : ""}${block.impact ? `<div class="finding-impact">${esc(block.impact)}</div>` : ""}</div>`;

    case "prediction":
      return `<div class="prediction"><div class="prediction-metric">${esc(block.metric)}</div><div><span class="prediction-value">${block.predicted.toLocaleString()}</span> <span class="prediction-detail">projected (current: ${block.current.toLocaleString()}) — ${esc(block.confidence)} confidence</span></div><div class="prediction-detail">${esc(block.timeframe)} · ${esc(block.basis)}</div>${block.caveat ? `<div class="prediction-caveat">${esc(block.caveat)}</div>` : ""}</div>`;

    case "recommendation":
      return `<div class="rec"><div class="rec-header"><span class="finding-num">${block.index}.</span><span class="badge badge-${block.priority}">${esc(block.priority)}</span><strong>${esc(block.title)}</strong>${block.citations ? ` <span style="color:#EF4444;font-size:10px;">${esc(block.citations)}</span>` : ""}</div><div class="rec-desc">${esc(block.description)}</div>${block.expectedImpact ? `<div class="rec-impact">Expected: ${esc(block.expectedImpact)}</div>` : ""}</div>`;

    case "source_row":
      return `<div class="source"><span><span class="source-dot ${block.status === "available" ? "source-available" : "source-missing"}"></span>${esc(block.label)}</span><span>${esc(block.status)}${block.recordCount ? ` (${block.recordCount} records)` : ""}</span></div>`;

    case "citation_list":
      return `<ul class="citations">${block.items.map(item =>
        `<li><strong style="color:#EF4444;">${esc(item.label)}</strong> ${item.url ? `<a href="${esc(item.url)}" style="color:#2563EB;">${esc(item.title)}</a>` : esc(item.title)} <span style="color:#94a3b8;">— ${esc(item.sourceName)}</span></li>`
      ).join("")}</ul>`;

    case "divider":
      return `<div class="divider"></div>`;

    case "spacer":
      return `<div class="spacer"></div>`;

    case "footer":
      return `<p style="text-align:center;font-style:italic;color:#94a3b8;font-size:11px;margin-top:24px;">${esc(block.text)}</p>`;

    default:
      return "";
  }
}

function esc(s: string): string {
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}
