// Inlinr — ZIP export: generates production email HTML with inline CSS + asset bundling

const EMAIL_RESET_CSS = `
body,table,td,a{-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}
table,td{mso-table-lspace:0;mso-table-rspace:0}
img{-ms-interpolation-mode:bicubic;border:0;height:auto;line-height:100%;outline:none;text-decoration:none}
body{margin:0;padding:0;width:100%!important;-webkit-font-smoothing:antialiased}
table{border-collapse:collapse!important}
`;

const DARK_MODE_CSS = `
@media (prefers-color-scheme:dark){
  .email-body{background-color:#1a1a1e!important}
  .email-row{background-color:#1a1a1e!important}
  h1,h2,h3,h4,p,span,div,a{color:#e8e8ec!important}
  .dark-bg{background-color:var(--dark-bg)!important}
  .dark-text{color:var(--dark-text)!important}
  .dark-btn-bg{background-color:var(--dark-btn-bg)!important}
  .dark-btn-text{color:var(--dark-btn-text)!important}
}
`;

const px = (v) => v != null ? `${v}px` : undefined;
const pct = (v) => v != null ? `${v}%` : undefined;

const inlineStyle = (obj) => {
  return Object.entries(obj)
    .filter(([, v]) => v != null && v !== "" && v !== undefined)
    .map(([k, v]) => `${k.replace(/[A-Z]/g, m => "-" + m.toLowerCase())}:${v}`)
    .join(";");
};

const esc = (s) => (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");

const blockToRow = (block, imageFiles) => {
  const s = block.styles || {};
  const c = block.content || {};
  const ds = block.darkStyles || {};

  const wrapStyle = {
    paddingTop: px(s.paddingTop),
    paddingBottom: px(s.paddingBottom),
    paddingLeft: px(s.paddingLeft),
    paddingRight: px(s.paddingRight),
    backgroundColor: s.bgColor && s.bgColor !== "transparent" ? s.bgColor : undefined,
    borderRadius: px(s.borderRadius),
  };

  const txtStyle = {
    fontFamily: s.fontFamily || "'Plus Jakarta Sans',system-ui,sans-serif",
    fontSize: px(s.fontSize || 16),
    fontWeight: s.fontWeight || "400",
    textAlign: s.textAlign || "center",
    color: s.color && s.color !== "transparent" ? s.color : "#0c0c0e",
    lineHeight: s.lineHeight ? String(s.lineHeight) : "1.5",
  };

  const btnStyle = {
    display: "inline-block",
    background: s.buttonBg || "#3b6bff",
    color: s.buttonColor || "#ffffff",
    borderRadius: px(s.buttonRadius ?? 8),
    fontSize: px(s.buttonFontSize || 13),
    padding: s.buttonPaddingH != null ? `0 ${s.buttonPaddingH}px` : "0 18px",
    height: px(s.buttonHeight ?? 38),
    lineHeight: px(s.buttonHeight ?? 38),
    textDecoration: "none",
    fontWeight: "600",
    fontFamily: s.fontFamily || "'Plus Jakarta Sans',system-ui,sans-serif",
  };

  const darkAttrs = [];
  if (ds.bgColor) darkAttrs.push(`data-dark-bg="${esc(ds.bgColor)}"`);
  if (ds.color) darkAttrs.push(`data-dark-text="${esc(ds.color)}"`);
  if (ds.buttonBg) darkAttrs.push(`data-dark-btn-bg="${esc(ds.buttonBg)}"`);
  if (ds.buttonColor) darkAttrs.push(`data-dark-btn-text="${esc(ds.buttonColor)}"`);
  const darkData = darkAttrs.length ? " " + darkAttrs.join(" ") : "";

  const wrap = (inner) =>
    `<tr><td class="email-row" style="${inlineStyle(wrapStyle)}"${darkData}>${inner}</td></tr>`;

  switch (block.type) {
    case "hero": {
      const logo = `<div style="text-align:center;padding-bottom:16px">
        <img src="images/inlinr-mark.png" alt="Inlinr" width="78" height="20" style="display:inline-block" />
      </div>`;
      const eyebrow = c.eyebrow ? `<p style="${inlineStyle({ ...txtStyle, fontSize: "13px", fontWeight: "500", opacity: "0.6", marginBottom: "4px" })}">${esc(c.eyebrow)}</p>` : "";
      const heading = `<h1 style="${inlineStyle({ ...txtStyle, fontSize: px(s.fontSize || 32), fontWeight: "700", margin: "0 0 12px" })}">${esc(c.heading || "")}</h1>`;
      const body = c.body ? `<p style="${inlineStyle({ ...txtStyle, fontSize: "15px", fontWeight: "400", opacity: "0.7", maxWidth: "540px", margin: "0 auto 24px" })}">${esc(c.body)}</p>` : "";
      const cta = c.ctaText ? `<a href="${esc(c.ctaUrl || "#")}" style="${inlineStyle(btnStyle)}">${esc(c.ctaText)}</a>` : "";
      return wrap(`<div style="text-align:center">${logo}${eyebrow}${heading}${body}${cta}</div>`);
    }

    case "text": {
      const heading = c.heading ? `<h3 style="${inlineStyle({ ...txtStyle, fontSize: px(s.fontSize || 20), fontWeight: "600", margin: "0 0 8px" })}">${esc(c.heading)}</h3>` : "";
      const body = c.body ? `<p style="${inlineStyle({ ...txtStyle, fontSize: px(s.fontSize || 15), fontWeight: "400", margin: "0" })}">${esc(c.body)}</p>` : "";
      return wrap(heading + body);
    }

    case "image": {
      const src = c.src || "";
      let imgSrc = src;
      if (src && imageFiles.has(src)) {
        imgSrc = `images/${imageFiles.get(src)}`;
      }
      const imgS = {
        display: "block",
        maxWidth: pct(s.maxWidth ?? 100),
        width: "100%",
        height: "auto",
        borderRadius: px(s.borderRadius ?? 4),
        margin: s.textAlign === "left" ? "0" : s.textAlign === "right" ? "0 0 0 auto" : "0 auto",
      };
      const img = src ? `<img src="${esc(imgSrc)}" alt="${esc(c.alt || "")}" style="${inlineStyle(imgS)}" />` : "";
      const inner = c.linkUrl ? `<a href="${esc(c.linkUrl)}">${img}</a>` : img;
      return wrap(`<div style="text-align:${s.textAlign || "center"}">${inner}</div>`);
    }

    case "columns": {
      const cols = c.columns || [];
      const colCount = s.colCount || cols.length || 3;
      const gap = s.colGap ?? 16;
      const colWidth = Math.floor((600 - gap * (colCount - 1)) / colCount);
      const colCells = cols.slice(0, colCount).map(col =>
        `<td style="width:${colWidth}px;vertical-align:top;padding:0 ${gap / 2}px;text-align:center">
          <h4 style="${inlineStyle({ ...txtStyle, fontSize: "15px", fontWeight: "600", margin: "0 0 4px" })}">${esc(col.heading || "")}</h4>
          <p style="${inlineStyle({ ...txtStyle, fontSize: "13px", fontWeight: "400", margin: "0", opacity: "0.7" })}">${esc(col.body || "")}</p>
        </td>`
      ).join("");
      return wrap(`<table width="100%" cellpadding="0" cellspacing="0" role="presentation"><tr>${colCells}</tr></table>`);
    }

    case "cta": {
      const heading = c.heading ? `<p style="${inlineStyle({ ...txtStyle, fontSize: px(s.fontSize || 16), fontWeight: "600", margin: "0 0 16px" })}">${esc(c.heading)}</p>` : "";
      const btn = c.buttonText ? `<a href="${esc(c.buttonUrl || "#")}" style="${inlineStyle(btnStyle)}">${esc(c.buttonText)}</a>` : "";
      const sub = c.sub ? `<p style="${inlineStyle({ ...txtStyle, fontSize: "12px", fontWeight: "400", opacity: "0.5", margin: "12px 0 0" })}">${esc(c.sub)}</p>` : "";
      return wrap(`<div style="text-align:center">${heading}${btn}${sub}</div>`);
    }

    case "divider": {
      const dColor = s.color && s.color !== "transparent" ? s.color : "#e4e4e7";
      const dWidth = pct(s.dividerWidth ?? 100);
      const thickness = s.thickness || 1;
      const style = s.borderStyle || "solid";
      return wrap(`<div style="text-align:center"><hr style="border:none;border-top:${thickness}px ${style} ${dColor};width:${dWidth};margin:0 auto" /></div>`);
    }

    case "spacer": {
      const h = s.height || 32;
      return wrap(`<div style="height:${h}px;line-height:${h}px;font-size:1px">&nbsp;</div>`);
    }

    case "footer": {
      const footerTxt = {
        fontFamily: "'Plus Jakarta Sans',system-ui,sans-serif",
        fontSize: "12px",
        color: "#9e9ea8",
        textAlign: "center",
        lineHeight: "1.5",
      };
      const links = c.links ? `<p style="${inlineStyle({ ...footerTxt, margin: "0 0 8px" })}">${esc(c.links)}</p>` : "";
      const legal = c.legal ? `<p style="${inlineStyle({ ...footerTxt, fontSize: "11px", opacity: "0.7", margin: "0" })}">${esc(c.legal)}</p>` : "";
      return wrap(`<div style="text-align:center;padding:24px 0">${links}${legal}</div>`);
    }

    default:
      return "";
  }
};

const generateEmailHTML = (blocks, subject, previewText) => {
  const imageFiles = new Map();

  const rows = blocks.map(b => blockToRow(b, imageFiles)).join("\n");

  return `<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="x-apple-disable-message-reformatting">
<title>${esc(subject || "")}</title>
<!--[if mso]><noscript><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml></noscript><![endif]-->
<style>${EMAIL_RESET_CSS}${DARK_MODE_CSS}
.email-container{max-width:720px;margin:0 auto}
@media only screen and (max-width:480px){
  .email-container{width:100%!important;max-width:100%!important}
  td.email-row{padding-left:16px!important;padding-right:16px!important}
}
</style>
</head>
<body style="margin:0;padding:0;background-color:#f4f4f7">
${previewText ? `<div style="display:none;font-size:1px;color:#f4f4f7;line-height:1px;max-height:0;max-width:0;opacity:0;overflow:hidden">${esc(previewText)}</div>` : ""}
<center style="width:100%;background-color:#f4f4f7">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr><td>
<table class="email-container" role="presentation" cellspacing="0" cellpadding="0" border="0" width="720" align="center" style="margin:0 auto">
${rows}
</table>
</td></tr>
</table>
</center>
</body>
</html>`;
};

const fetchImageAsBlob = async (url) => {
  try {
    const resp = await fetch(url, { mode: "cors" });
    if (!resp.ok) return null;
    return await resp.blob();
  } catch {
    return null;
  }
};

const exportZip = async (blocks, subject, previewText, onProgress) => {
  onProgress?.("Generating HTML…");
  const html = generateEmailHTML(blocks, subject, previewText);

  const zip = new JSZip();
  const imgFolder = zip.folder("images");

  const imageUrls = blocks
    .filter(b => b.type === "image" && b.content?.src)
    .map(b => b.content.src);

  const uniqueUrls = [...new Set(imageUrls)];
  let finalHtml = html;

  if (uniqueUrls.length > 0) {
    onProgress?.(`Bundling ${uniqueUrls.length} image${uniqueUrls.length > 1 ? "s" : ""}…`);
    for (let i = 0; i < uniqueUrls.length; i++) {
      const url = uniqueUrls[i];
      const blob = await fetchImageAsBlob(url);
      if (blob) {
        const ext = (blob.type || "image/png").split("/")[1] || "png";
        const name = `image-${i + 1}.${ext}`;
        imgFolder.file(name, blob);
        finalHtml = finalHtml.split(url).join(`images/${name}`);
      }
    }
  }

  zip.file("email.html", finalHtml);

  const txtContent = blocks.map(b => {
    const c = b.content || {};
    return [c.eyebrow, c.heading, c.body, c.buttonText, c.sub, c.links, c.legal]
      .filter(Boolean).join("\n");
  }).filter(Boolean).join("\n\n");
  zip.file("email.txt", txtContent);

  onProgress?.("Packaging ZIP…");
  const blob = await zip.generateAsync({ type: "blob", compression: "DEFLATE", compressionOptions: { level: 6 } });

  const safeName = (subject || "email").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 40);
  const filename = `${safeName}.zip`;

  const a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(a.href);

  const sizeKB = Math.round(blob.size / 1024);
  return { filename, sizeKB };
};

Object.assign(window, { generateEmailHTML, exportZip });
