import { SortDir } from "./types.js";
const toSnakeCase = (value) => value.replace(/([A-Z])/g, "_$1").replace(/__/g, "_").toLowerCase();
const toCamelCase = (value) => value.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
function fieldNameCandidates(field) {
  const raw = String(field || "").trim();
  if (!raw) return [];
  const candidates = [raw, toSnakeCase(raw), toCamelCase(raw)];
  if (raw.startsWith("cf:")) candidates.push(raw.replace(/[^a-zA-Z0-9_]/g, "_"));
  return Array.from(new Set(candidates));
}
function resolveEncryptedSortMaxRows() {
  const raw = process.env.OM_ENCRYPTED_SORT_MAX_ROWS;
  if (raw === void 0 || raw === "") return null;
  const parsed = Number(raw);
  if (!Number.isFinite(parsed) || parsed <= 0) return null;
  return Math.floor(parsed);
}
async function resolveEncryptedSortFields(service, entity, sortFields, tenantId, organizationId) {
  if (!service?.getEncryptedFieldNames) return /* @__PURE__ */ new Set();
  if (service.isEnabled && !service.isEnabled()) return /* @__PURE__ */ new Set();
  const encrypted = await service.getEncryptedFieldNames(entity, tenantId ?? null, organizationId ?? null);
  const encryptedCandidates = /* @__PURE__ */ new Set();
  for (const field of encrypted) {
    for (const candidate of fieldNameCandidates(field)) encryptedCandidates.add(candidate);
  }
  const result = /* @__PURE__ */ new Set();
  for (const field of sortFields) {
    if (field.startsWith("cf:")) continue;
    const matches = fieldNameCandidates(field).some((candidate) => encryptedCandidates.has(candidate));
    if (matches) result.add(field);
  }
  return result;
}
function readField(row, field) {
  for (const candidate of fieldNameCandidates(field)) {
    if (Object.prototype.hasOwnProperty.call(row, candidate)) return row[candidate];
  }
  return void 0;
}
function compareValues(left, right) {
  const leftMissing = left === null || left === void 0;
  const rightMissing = right === null || right === void 0;
  if (leftMissing && rightMissing) return 0;
  if (leftMissing) return 1;
  if (rightMissing) return -1;
  if (left instanceof Date && right instanceof Date) return left.getTime() - right.getTime();
  if (typeof left === "number" && typeof right === "number") return left - right;
  if (typeof left === "boolean" && typeof right === "boolean") return Number(left) - Number(right);
  return String(left).localeCompare(String(right), void 0, {
    sensitivity: "base",
    numeric: true
  });
}
function sortRowsInMemory(rows, sorts) {
  return [...rows].sort((left, right) => {
    for (const sort of sorts) {
      const direction = sort.dir === SortDir.Desc ? -1 : 1;
      const compared = compareValues(readField(left, sort.field), readField(right, sort.field));
      if (compared !== 0) return compared * direction;
    }
    const leftId = readField(left, "id");
    const rightId = readField(right, "id");
    return compareValues(leftId, rightId);
  });
}
export {
  fieldNameCandidates,
  resolveEncryptedSortFields,
  resolveEncryptedSortMaxRows,
  sortRowsInMemory
};
//# sourceMappingURL=encrypted-sort.js.map
