/* ATLAS — report generation (PPTX / DOCX), fully client-side.
   The AI returns a `generate_document` client tool whose input is a REPORT SPEC. This
   module previews it (ReportCard) and, on demand, rasterises any embedded chart specs to
   PNG (via window.AtlasChartPNG) and assembles a .pptx (PptxGenJS) or .docx (docx UMD),
   then triggers a download. Keeps generation where the data + chart renderer already live.

   Report spec shape:
     { title: string, subtitle?: string,
       sections: [ {
         heading: string,
         paragraphs?: [string],
         bullets?: [string],
         table?: { columns: [string], rows: [[cell]] },
         chart?: <chart spec>          // see agent-charts.jsx
       } ],
       recommendations?: [ { name, horizon, targetsMetric, impact, why } ],
       footer?: string }

   Exposes: window.AtlasReportCard (React component). */
(function () {
  "use strict";
  const { useState } = React;
  const h = React.createElement;
  const BRAND = "074D47", ACCENT = "22867C", INK = "111827", MUTE = "4B5563";

  function validate(spec) {
    if (!spec || typeof spec !== "object") return { ok: false, error: "Report spec missing." };
    if (!spec.title) return { ok: false, error: "Report has no title." };
    if (!Array.isArray(spec.sections) || !spec.sections.length) return { ok: false, error: "Report has no sections." };
    return { ok: true };
  }

  function safeName(spec, ext) {
    return (spec.title || "atlas-report").replace(/[^\w]+/g, "-").toLowerCase().slice(0, 60) + "." + ext;
  }

  // rasterise every section.chart -> { [sectionIndex]: dataURL }
  async function renderCharts(spec) {
    const out = {};
    for (let i = 0; i < spec.sections.length; i++) {
      const c = spec.sections[i].chart;
      if (!c) continue;
      try { out[i] = await window.AtlasChartPNG(c, { width: 560, height: 320 }); } catch (e) { /* skip bad chart */ }
    }
    return out;
  }

  function download(blobOrUrl, name) {
    const url = typeof blobOrUrl === "string" ? blobOrUrl : URL.createObjectURL(blobOrUrl);
    const a = document.createElement("a"); a.href = url; a.download = name; a.click();
    if (typeof blobOrUrl !== "string") setTimeout(() => URL.revokeObjectURL(url), 4000);
  }

  // ---------- PPTX ----------
  async function buildPptx(spec) {
    const charts = await renderCharts(spec);
    const pptx = new window.PptxGenJS();
    pptx.layout = "LAYOUT_WIDE";
    pptx.defineSlideMaster({
      title: "ATLAS",
      background: { color: "FFFFFF" },
      objects: [{ rect: { x: 0, y: 0, w: "100%", h: 0.18, fill: { color: BRAND } } }],
    });

    // title slide
    const t = pptx.addSlide({ masterName: "ATLAS" });
    t.addText(spec.title, { x: 0.6, y: 2.1, w: 12, h: 1.0, fontSize: 34, bold: true, color: BRAND });
    if (spec.subtitle) t.addText(spec.subtitle, { x: 0.6, y: 3.1, w: 12, h: 0.6, fontSize: 16, color: MUTE });
    t.addText("ATLAS · Cement decarbonisation analysis", { x: 0.6, y: 6.7, w: 12, h: 0.4, fontSize: 11, color: ACCENT });

    spec.sections.forEach((sec, i) => {
      const s = pptx.addSlide({ masterName: "ATLAS" });
      s.addText(sec.heading || "Section " + (i + 1), { x: 0.6, y: 0.45, w: 12, h: 0.7, fontSize: 22, bold: true, color: BRAND });
      let y = 1.35;
      (sec.paragraphs || []).forEach((p) => {
        s.addText(p, { x: 0.6, y, w: charts[i] ? 6.2 : 12, h: 0.8, fontSize: 13, color: INK, valign: "top" });
        y += 0.9;
      });
      if (sec.bullets && sec.bullets.length) {
        s.addText(sec.bullets.map((b) => ({ text: b, options: { bullet: true } })),
          { x: 0.6, y, w: charts[i] ? 6.2 : 12, h: 3, fontSize: 13, color: INK, valign: "top" });
      }
      if (sec.table && sec.table.columns) {
        const head = sec.table.columns.map((c) => ({ text: String(c), options: { bold: true, color: "FFFFFF", fill: { color: BRAND } } }));
        const rows = (sec.table.rows || []).map((r) => r.map((c) => ({ text: String(c), options: { color: INK } })));
        s.addTable([head].concat(rows), { x: 0.6, y: Math.max(y, 1.5), w: charts[i] ? 6.2 : 12, fontSize: 11, border: { type: "solid", color: "E5E7EB", pt: 0.5 } });
      }
      if (charts[i]) s.addImage({ data: charts[i], x: 7.0, y: 1.35, w: 5.6, h: 3.2 });
    });

    // recommendations slide
    if (spec.recommendations && spec.recommendations.length) {
      const r = pptx.addSlide({ masterName: "ATLAS" });
      r.addText("Recommended decarbonisation levers", { x: 0.6, y: 0.45, w: 12, h: 0.7, fontSize: 22, bold: true, color: BRAND });
      const head = ["Lever", "Horizon", "Targets", "Indicative impact", "Why"].map((c) => ({ text: c, options: { bold: true, color: "FFFFFF", fill: { color: ACCENT } } }));
      const rows = spec.recommendations.map((rec) => [
        rec.name || "", rec.horizon || "", rec.targetsMetric || "",
        impactText(rec.impact), rec.why || "",
      ].map((c) => ({ text: String(c), options: { color: INK, fontSize: 10 } })));
      r.addTable([head].concat(rows), { x: 0.6, y: 1.4, w: 12.1, colW: [2.6, 1.2, 1.6, 2.7, 4.0], fontSize: 10, border: { type: "solid", color: "E5E7EB", pt: 0.5 }, valign: "top" });
      r.addText("Impact ranges are indicative public planning figures, not site-engineered estimates.",
        { x: 0.6, y: 6.9, w: 12, h: 0.3, fontSize: 9, italic: true, color: MUTE });
    }

    const blob = await pptx.write({ outputType: "blob" });
    download(blob, safeName(spec, "pptx"));
  }

  // ---------- DOCX ----------
  async function buildDocx(spec) {
    const D = window.docx;
    const charts = await renderCharts(spec);
    const children = [];

    children.push(new D.Paragraph({ text: spec.title, heading: D.HeadingLevel.TITLE }));
    if (spec.subtitle) children.push(new D.Paragraph({ children: [new D.TextRun({ text: spec.subtitle, italics: true, color: MUTE })] }));

    for (let i = 0; i < spec.sections.length; i++) {
      const sec = spec.sections[i];
      children.push(new D.Paragraph({ text: sec.heading || "Section " + (i + 1), heading: D.HeadingLevel.HEADING_1 }));
      (sec.paragraphs || []).forEach((p) => children.push(new D.Paragraph({ text: p })));
      (sec.bullets || []).forEach((b) => children.push(new D.Paragraph({ text: b, bullet: { level: 0 } })));
      if (sec.table && sec.table.columns) children.push(buildDocxTable(D, sec.table));
      if (charts[i]) {
        const data = dataUrlToUint8(charts[i]);
        if (data) children.push(new D.Paragraph({ children: [new D.ImageRun({ data, transformation: { width: 520, height: 297 } })] }));
      }
    }

    if (spec.recommendations && spec.recommendations.length) {
      children.push(new D.Paragraph({ text: "Recommended decarbonisation levers", heading: D.HeadingLevel.HEADING_1 }));
      children.push(buildDocxTable(D, {
        columns: ["Lever", "Horizon", "Targets", "Indicative impact", "Why"],
        rows: spec.recommendations.map((r) => [r.name || "", r.horizon || "", r.targetsMetric || "", impactText(r.impact), r.why || ""]),
      }));
      children.push(new D.Paragraph({ children: [new D.TextRun({ text: "Impact ranges are indicative public planning figures, not site-engineered estimates.", italics: true, size: 18, color: MUTE })] }));
    }
    if (spec.footer) children.push(new D.Paragraph({ children: [new D.TextRun({ text: spec.footer, size: 18, color: MUTE })] }));

    const doc = new D.Document({ sections: [{ children }] });
    const blob = await D.Packer.toBlob(doc);
    download(blob, safeName(spec, "docx"));
  }

  function buildDocxTable(D, table) {
    const header = new D.TableRow({
      children: (table.columns || []).map((c) => new D.TableCell({
        shading: { fill: BRAND }, children: [new D.Paragraph({ children: [new D.TextRun({ text: String(c), bold: true, color: "FFFFFF" })] })],
      })),
    });
    const body = (table.rows || []).map((r) => new D.TableRow({
      children: r.map((c) => new D.TableCell({ children: [new D.Paragraph({ text: String(c) })] })),
    }));
    return new D.Table({ rows: [header].concat(body), width: { size: 100, type: D.WidthType.PERCENTAGE } });
  }

  // ---------- helpers ----------
  function impactText(imp) {
    if (!imp) return "—";
    const lo = imp.low, hi = imp.high, u = imp.unit || "";
    if (typeof lo === "number" && typeof hi === "number") return lo + "–" + hi + " " + u;
    return String(imp.value != null ? imp.value : "") + " " + u;
  }
  function dataUrlToUint8(dataUrl) {
    try {
      const b64 = dataUrl.split(",")[1];
      const bin = atob(b64);
      const arr = new Uint8Array(bin.length);
      for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);
      return arr;
    } catch (e) { return null; }
  }

  // ---------- React preview card ----------
  function ReportCard({ spec, onDone }) {
    const [busy, setBusy] = useState("");
    const [err, setErr] = useState(null);
    const v = validate(spec);
    if (!v.ok) return h("div", { className: "agent-chart error" }, "Report could not be prepared: " + v.error);

    const run = (fmt) => async () => {
      setBusy(fmt); setErr(null);
      try { fmt === "pptx" ? await buildPptx(spec) : await buildDocx(spec); if (onDone) onDone(fmt); }
      catch (e) { setErr(e.message || String(e)); }
      finally { setBusy(""); }
    };

    const chartCount = spec.sections.filter((s) => s.chart).length;
    return h("div", { className: "report-card" },
      h("div", { className: "report-card-head" }, "Report ready — " + spec.title),
      h("div", { className: "report-card-body" },
        spec.subtitle ? h("div", null, spec.subtitle) : null,
        h("ul", null,
          spec.sections.slice(0, 8).map((s, i) => h("li", { key: i }, s.heading || "Section " + (i + 1))),
        ),
        h("div", { style: { marginTop: 6, color: "#4B5563" } },
          spec.sections.length + " sections · " + chartCount + " chart(s)" +
          (spec.recommendations ? " · " + spec.recommendations.length + " levers" : "")),
        err ? h("div", { style: { marginTop: 6, color: "#B45309" } }, "Error: " + err) : null,
      ),
      h("div", { className: "report-card-actions" },
        h("button", { className: "report-btn", type: "button", disabled: !!busy, onClick: run("pptx") },
          busy === "pptx" ? "Building…" : "Download PPTX"),
        h("button", { className: "report-btn alt", type: "button", disabled: !!busy, onClick: run("docx") },
          busy === "docx" ? "Building…" : "Download DOCX"),
      ),
    );
  }

  window.AtlasReportCard = ReportCard;
  window.AtlasReport = { validate, buildPptx, buildDocx };
})();
