// lib/exporter.js — zero-dependency exports, client-side only.
// Student version and teacher version (with red-pen answer key), as:
// plain text, Word (.doc via HTML), clipboard, and print (for PDF).
import { totalPoints } from "@/lib/schema";

const LETTERS = "ABCDEFGHIJ";

function answersLine(q) {
  switch (q.type) {
    case "multiple_choice":
      return `Answer: ${LETTERS[q.correctIndex] || "?"} — ${q.options?.[q.correctIndex] || ""}`;
    case "true_false":
      return `Answer: ${q.correctAnswer ? "True" : "False"}`;
    case "short_answer":
      return `Sample answer: ${q.sampleAnswer || ""}` + (q.keyPoints?.length ? `\nMust include: ${q.keyPoints.join("; ")}` : "");
    case "essay":
      return (q.sampleResponse ? `Sample response: ${q.sampleResponse}` : "") +
        (q.rubric?.length ? `\nRubric:\n${q.rubric.map((r) => `  • ${r.criterion} (${r.points} pts)${r.description ? " — " + r.description : ""}`).join("\n")}` : "");
    case "fill_blank":
      return `Answers: ${(q.answers || []).map((a, i) => `(${i + 1}) ${a}`).join("  ")}`;
    case "matching":
      return `Answer key:\n${(q.pairs || []).map((p) => `  ${p.left} → ${p.right}`).join("\n")}`;
    case "discussion":
      return (q.talkingPoints?.length ? `Key talking points:\n${q.talkingPoints.map((t) => `  • ${t}`).join("\n")}` : "") +
        (q.followUps?.length ? `\nFollow-ups:\n${q.followUps.map((t) => `  • ${t}`).join("\n")}` : "") +
        (q.sampleResponse ? `\nA strong contribution: ${q.sampleResponse}` : "");
    default:
      return "";
  }
}

// Shuffle the right column of a matching question deterministically (by text)
// so the student version isn't pre-matched but exports are stable.
function shuffledRight(pairs) {
  return [...pairs.map((p) => p.right)].sort((a, b) => a.localeCompare(b));
}

function questionStudentText(q, n) {
  const head = `${n}. ${q.type === "matching" ? (q.question || "Match each item on the left with the correct item on the right.") : q.question}  (${q.points} pt${q.points === 1 ? "" : "s"})`;
  let body = "";
  if (q.type === "multiple_choice") {
    body = (q.options || []).map((o, i) => `   ${LETTERS[i]}. ${o}`).join("\n");
  } else if (q.type === "true_false") {
    body = "   True  /  False";
  } else if (q.type === "short_answer") {
    body = "   ________________________________________________\n   ________________________________________________";
  } else if (q.type === "essay" || q.type === "discussion") {
    body = "";
  } else if (q.type === "matching") {
    const rights = shuffledRight(q.pairs || []);
    body = (q.pairs || []).map((p, i) => `   ___ ${i + 1}. ${p.left}`).join("\n") +
      "\n\n" + rights.map((r, i) => `       ${LETTERS[i]}. ${r}`).join("\n");
  }
  return body ? head + "\n" + body : head;
}

export function buildText(assignment, { teacher, profile = {} }) {
  const lines = [];
  const teachLine = [profile.teacherName, profile.className].filter(Boolean).join(" — ");
  if (profile.schoolName) lines.push(profile.schoolName);
  if (teachLine) lines.push(teachLine);
  if (profile.schoolName || teachLine) lines.push("");
  lines.push(assignment.title || "Untitled assignment");
  const meta = [assignment.subject, assignment.gradeLevel, totalPoints(assignment.questions) + " points"].filter(Boolean).join("  ·  ");
  lines.push(meta);
  if (teacher) lines.push("TEACHER VERSION — ANSWER KEY INCLUDED");
  lines.push("");
  if (!teacher) lines.push("Name: ______________________________    Date: ______________", "");
  if (assignment.instructions) lines.push("Instructions: " + assignment.instructions, "");
  if (assignment.caseStudy) lines.push("— Read the following —", "", assignment.caseStudy, "");

  assignment.questions.forEach((q, i) => {
    lines.push(questionStudentText(q, i + 1));
    if (teacher) {
      const ans = answersLine(q);
      if (ans) lines.push("   ✎ " + ans.replace(/\n/g, "\n   "));
      if (q.explanation) lines.push("   ✎ Explanation: " + q.explanation);
      if (q.sourceRef) lines.push("   ✎ Source: \u201C" + q.sourceRef + "\u201D");
      if (q.verification?.status === "warn") lines.push("   ⚠ Reviewer note: " + (q.verification.note || "flagged — double-check"));
    }
    lines.push("");
  });
  return lines.join("\n");
}

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

function schoolHeadHtml(profile = {}) {
  const teachLine = [profile.teacherName, profile.className].filter(Boolean).join(" — ");
  if (!profile.logo && !profile.schoolName && !teachLine) return "";
  return `<div class="schoolhead">
${profile.logo ? `<img class="schoollogo" src="${profile.logo}" alt="">` : ""}
<div class="schoolinfo">
${profile.schoolName ? `<div class="schoolname">${esc(profile.schoolName)}</div>` : ""}
${teachLine ? `<div class="teachline">${esc(teachLine)}</div>` : ""}
</div>
</div>`;
}

function buildBodyHtml(assignment, { teacher, profile }) {
  const qs = assignment.questions || [];
  const qHtml = qs.map((q, i) => {
    const n = i + 1;
    let body = "";
    if (q.type === "multiple_choice") {
      body = `<div class="opts">` + (q.options || []).map((o, j) => {
        const isAns = teacher && j === q.correctIndex;
        return `<div${isAns ? ' class="ans"' : ""}>${LETTERS[j]}. ${esc(o)}${isAns ? " ✓" : ""}</div>`;
      }).join("") + `</div>`;
    } else if (q.type === "true_false") {
      body = `<div class="opts">True&nbsp;&nbsp;/&nbsp;&nbsp;False${teacher ? ` <span class="ans">✓ ${q.correctAnswer ? "True" : "False"}</span>` : ""}</div>`;
    } else if (q.type === "short_answer") {
      body = teacher ? "" : `<div class="writelines"></div><div class="writelines"></div>`;
    } else if (q.type === "essay" || q.type === "discussion") {
      body = "";
    } else if (q.type === "fill_blank") {
      body = "";
    } else if (q.type === "matching") {
      const rights = shuffledRight(q.pairs || []);
      body = `<table class="match"><tr><td>` +
        (q.pairs || []).map((p, j) => `<div>___ ${j + 1}. ${esc(p.left)}</div>`).join("") +
        `</td><td>` + rights.map((r, j) => `<div>${LETTERS[j]}. ${esc(r)}</div>`).join("") +
        `</td></tr></table>`;
    }

    let key = "";
    if (teacher) {
      const ans = answersLine(q);
      key = `<div class="key">` +
        (ans ? `<div>${esc(ans).replace(/\n/g, "<br>")}</div>` : "") +
        (q.explanation ? `<div><b>Explanation:</b> ${esc(q.explanation)}</div>` : "") +
        (q.sourceRef ? `<div><b>Source:</b> \u201C${esc(q.sourceRef)}\u201D</div>` : "") +
        (q.verification?.status === "warn" ? `<div class="warnnote">⚠ Reviewer note: ${esc(q.verification.note || "flagged")}</div>` : "") +
        `</div>`;
    }
    const prompt = q.type === "matching" ? (q.question || "Match each item on the left with the correct item on the right.") : q.question;
    return `<div class="q"><p class="qp"><b>${n}.</b> ${esc(prompt)} <span class="pts">(${q.points} pt${q.points === 1 ? "" : "s"})</span></p>${body}${key}</div>`;
  }).join("");

  return `${schoolHeadHtml(profile)}<h1>${esc(assignment.title)}</h1>
<div class="meta">${esc([assignment.subject, assignment.gradeLevel].filter(Boolean).join("  ·  "))}  ·  ${totalPoints(qs)} points</div>
${teacher ? `<div class="teacherbar">Teacher version — answer key</div>` : `<div class="nameline">Name: ____________________________________&nbsp;&nbsp;&nbsp;Date: ________________</div>`}
${assignment.instructions ? `<p class="instr"><b>Instructions:</b> ${esc(assignment.instructions)}</p>` : ""}
${assignment.caseStudy ? `<div class="case">${esc(assignment.caseStudy).replace(/\n/g, "<br>")}</div>` : ""}
<hr>
${qHtml}`;
}

const PRINT_STYLES = `
  body { font-family: Georgia, "Times New Roman", serif; color: #1a1a1a; max-width: 7.2in; margin: 0 auto; padding: 24px; font-size: 12.5pt; line-height: 1.5; }
  h1 { font-size: 17pt; margin: 0 0 2px; }
  .meta { color: #555; font-size: 10.5pt; margin-bottom: 4px; }
  .teacherbar { color: #b8412f; font-weight: bold; font-size: 10.5pt; letter-spacing: 0.06em; text-transform: uppercase; border: 1.5pt solid #b8412f; display: inline-block; padding: 2px 8px; margin: 4px 0 10px; }
  .nameline { margin: 10px 0 14px; }
  .instr { margin: 0 0 14px; }
  .case { border: 1pt solid #999; padding: 12px 14px; margin: 0 0 16px; background: #fafafa; }
  .q { margin: 0 0 16px; page-break-inside: avoid; }
  .qp { margin: 0 0 4px; }
  .pts { color: #666; font-size: 10pt; }
  .opts { margin-left: 22px; }
  .opts div { margin: 2px 0; }
  .writelines { border-bottom: 1pt solid #888; height: 22px; margin: 8px 0 0 22px; }
  .match td { vertical-align: top; padding-right: 36px; }
  .match div { margin: 3px 0; }
  .ans { color: #b8412f; font-weight: bold; }
  .key { border-left: 2.5pt solid #b8412f; background: #fdf1ee; color: #7c2c1e; padding: 7px 11px; margin: 7px 0 0 22px; font-size: 11pt; }
  .key div { margin: 2px 0; }
  .warnnote { color: #8a6414; }
  hr { border: 0; border-top: 1pt solid #ccc; margin: 14px 0; }
  .schoolhead { display: flex; align-items: center; gap: 14px; border-bottom: 2pt solid #1a1a1a; padding-bottom: 9px; margin-bottom: 14px; }
  .schoollogo { height: 46pt; max-width: 130pt; object-fit: contain; flex: none; }
  .schoolname { font-size: 14pt; font-weight: bold; letter-spacing: 0.02em; }
  .teachline { font-size: 10.5pt; color: #444; }
  .pagebreak { page-break-after: always; break-after: page; }
  @media print { body { padding: 0; } }
`;

// opts: { teacher } for a single version, or { packet: true } for the student
// version followed by the answer key in one document (page break between).
// { word: true } switches the page-break markup to the form Word understands.
export function buildHtml(assignment, opts) {
  const profile = opts.profile || {};
  const sep = opts.word
    ? `<br clear="all" style="page-break-before:always">`
    : `<div class="pagebreak"></div>`;
  const body = opts.packet
    ? buildBodyHtml(assignment, { teacher: false, profile }) + sep + buildBodyHtml(assignment, { teacher: true, profile })
    : buildBodyHtml(assignment, { teacher: opts.teacher, profile });
  return `<!DOCTYPE html><html><head><meta charset="utf-8"><title>${esc(assignment.title)}</title>
<style>${PRINT_STYLES}</style></head><body>
${body}
</body></html>`;
}

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);
}

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

function variantSuffix(opts) {
  return opts.packet ? "packet" : opts.teacher ? "answer-key" : "student";
}

export function exportTxt(assignment, opts) {
  const text = buildText(assignment, opts);
  download(safeName(assignment.title, variantSuffix(opts), "txt"), new Blob([text], { type: "text/plain;charset=utf-8" }));
}

export function exportDoc(assignment, opts) {
  const html = buildHtml(assignment, { ...opts, word: true });
  download(
    safeName(assignment.title, variantSuffix(opts), "doc"),
    new Blob(["\ufeff" + html], { type: "application/msword" })
  );
}

export async function exportClipboard(assignment, opts) {
  await navigator.clipboard.writeText(buildText(assignment, opts));
}

export function exportPrint(assignment, opts) {
  const html = buildHtml(assignment, opts);
  const w = window.open("", "_blank");
  if (!w) throw new Error("Your browser blocked the print window. Allow pop-ups for this site and try again.");
  w.document.open();
  w.document.write(html);
  w.document.close();
  w.focus();
  setTimeout(() => w.print(), 400);
}
