const CSV_CONTENT_TYPE = "text/csv; charset=utf-8";
const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
const XML_CONTENT_TYPE = "application/xml; charset=utf-8";
const MARKDOWN_CONTENT_TYPE = "text/markdown; charset=utf-8";
function normalizeValue(value) {
  if (value == null) return "";
  if (value instanceof Date) return value.toISOString();
  if (typeof value === "bigint") return value.toString();
  if (typeof value === "object") {
    if (Array.isArray(value)) return value.map((v) => normalizeValue(v)).filter(Boolean).join(", ");
    return JSON.stringify(value);
  }
  return String(value);
}
function escapeCsv(value) {
  if (/[",\n\r]/.test(value)) {
    return `"${value.replace(/"/g, '""')}"`;
  }
  return value;
}
function neutralizeSpreadsheetFormula(value) {
  if (/^[=+\-@\t\r\n]/.test(value)) {
    return `'${value}`;
  }
  return value;
}
function normalizeCsvValue(value) {
  const normalized = normalizeValue(value);
  if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") {
    return normalized;
  }
  return neutralizeSpreadsheetFormula(normalized);
}
function escapeMarkdown(value) {
  const escaped = value.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\r?\n/g, "<br />");
  return escaped || " ";
}
function escapeXmlTag(tag, fallbackIndex) {
  const sanitized = tag.replace(/[^A-Za-z0-9_:-]/g, "_");
  const normalized = sanitized.length > 0 ? sanitized : `field_${fallbackIndex}`;
  if (/^[^A-Za-z_]/.test(normalized)) {
    return `f_${normalized}`;
  }
  return normalized;
}
function escapeXmlValue(value) {
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
}
function serializeCsv(prepared) {
  const headers = prepared.columns.map((col) => col.header);
  const lines = [headers.join(",")];
  for (const row of prepared.rows) {
    const values = prepared.columns.map((col) => {
      const raw = normalizeCsvValue(row[col.field]);
      return escapeCsv(raw);
    });
    lines.push(values.join(","));
  }
  return {
    body: lines.join("\n"),
    contentType: CSV_CONTENT_TYPE,
    fileExtension: "csv"
  };
}
function serializeJson(prepared) {
  const payload = prepared.rows.map((row) => {
    const obj = {};
    for (const column of prepared.columns) {
      obj[column.header] = row[column.field];
    }
    return obj;
  });
  return {
    body: JSON.stringify(payload, null, 2),
    contentType: JSON_CONTENT_TYPE,
    fileExtension: "json"
  };
}
function serializeXml(prepared) {
  const lines = ['<?xml version="1.0" encoding="UTF-8"?>', "<records>"];
  for (const row of prepared.rows) {
    lines.push("  <record>");
    prepared.columns.forEach((column, index) => {
      const tag = escapeXmlTag(column.field || column.header, index);
      const value = escapeXmlValue(normalizeValue(row[column.field]));
      lines.push(`    <${tag}>${value}</${tag}>`);
    });
    lines.push("  </record>");
  }
  lines.push("</records>");
  return {
    body: lines.join("\n"),
    contentType: XML_CONTENT_TYPE,
    fileExtension: "xml"
  };
}
function serializeMarkdown(prepared) {
  const headers = prepared.columns.map((col) => escapeMarkdown(col.header));
  const headerLine = `| ${headers.join(" | ")} |`;
  const dividerLine = `| ${prepared.columns.map(() => "---").join(" | ")} |`;
  const rows = prepared.rows.map((row) => {
    const cells = prepared.columns.map((col) => escapeMarkdown(normalizeValue(row[col.field])));
    return `| ${cells.join(" | ")} |`;
  });
  const body = [headerLine, dividerLine, ...rows].join("\n");
  return {
    body,
    contentType: MARKDOWN_CONTENT_TYPE,
    fileExtension: "md"
  };
}
function serializeExport(prepared, format) {
  switch (format) {
    case "csv":
      return serializeCsv(prepared);
    case "json":
      return serializeJson(prepared);
    case "xml":
      return serializeXml(prepared);
    case "markdown":
      return serializeMarkdown(prepared);
    default:
      return serializeJson(prepared);
  }
}
function normalizeExportFormat(raw) {
  if (typeof raw !== "string" || raw.trim() === "") return null;
  const value = raw.toLowerCase();
  if (value === "csv") return "csv";
  if (value === "json" || value === "application/json") return "json";
  if (value === "xml" || value === "application/xml") return "xml";
  if (value === "markdown" || value === "md" || value === "text/markdown") return "markdown";
  return null;
}
function defaultExportFilename(base, format) {
  const safeBase = (base && base.trim().length > 0 ? base.trim() : "export").replace(/[^a-z0-9_\-]/gi, "_");
  const suffix = format === "markdown" ? "md" : format;
  return `${safeBase}.${suffix}`;
}
function toHeaderLabel(key) {
  const withoutPrefix = key.replace(/^cf[:_\-\s]+/i, "");
  const normalized = withoutPrefix.replace(/[_\-\s]+/g, " ").trim();
  if (!normalized) return "Field";
  return normalized.replace(/\b\w/g, (char) => char.toUpperCase());
}
function ensureColumns(rows, hint) {
  if (hint && hint.length > 0) return hint;
  const used = /* @__PURE__ */ new Map();
  rows.forEach((row) => {
    Object.keys(row || {}).forEach((key) => {
      if (!used.has(key)) used.set(key, key);
    });
  });
  if (used.size === 0) return [{ field: "id", header: "ID" }];
  return Array.from(used.keys()).map((key) => ({
    field: key,
    header: toHeaderLabel(key)
  }));
}
export {
  defaultExportFilename,
  ensureColumns,
  normalizeExportFormat,
  serializeExport,
  toHeaderLabel
};
//# sourceMappingURL=exporters.js.map
