// lib/canvas/export.js — assemble a Canvas QTI .zip from an assignment and download it.
// Client-side only (like lib/exporter.js): no data leaves the browser.
import { mapAssignmentToCanvas } from "./map";
import { renderAssessmentXml } from "./qti";
import { renderManifest, renderAssessmentMeta } from "./manifest";
import { storeZip } from "./zip";

// A QTI identifier must be a valid NCName-ish token (starts with a letter, no spaces).
function slugIdent(seed) {
  const clean = String(seed || "").replace(/[^a-zA-Z0-9]/g, "");
  return "g" + (clean || "quiz");
}

function safeName(title) {
  const base = String(title || "quiz")
    .replace(/[^\w\- ]+/g, "").trim().replace(/\s+/g, "-").slice(0, 60) || "quiz";
  return `${base}-canvas.zip`;
}

// Build the package in memory. Returns { bytes: Uint8Array, ir, files } — pure, testable.
export function buildCanvasPackage(assignment, opts = {}) {
  const ir = mapAssignmentToCanvas(assignment, opts);
  const assessmentIdent = slugIdent(assignment?.id || assignment?.title);
  const manifestIdent = "m" + assessmentIdent;
  const files = [
    { name: "imsmanifest.xml", data: renderManifest(assessmentIdent, manifestIdent) },
    { name: `${assessmentIdent}/${assessmentIdent}.xml`, data: renderAssessmentXml(ir, assessmentIdent) },
    { name: `${assessmentIdent}/assessment_meta.xml`, data: renderAssessmentMeta(ir, assessmentIdent) },
  ];
  return { bytes: storeZip(files), ir, files };
}

function download(filename, blob) {
  const a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  setTimeout(() => { URL.revokeObjectURL(a.href); a.remove(); }, 800);
}

// Build and trigger the browser download. Returns the IR (so callers can show a summary).
export function exportCanvasZip(assignment, opts = {}) {
  const { bytes, ir } = buildCanvasPackage(assignment, opts);
  // Copy into a fresh ArrayBuffer so Blob gets a clean, correctly-sized buffer.
  const blob = new Blob([bytes.slice()], { type: "application/zip" });
  download(safeName(assignment?.title), blob);
  return ir;
}
