'use strict';

const HELPER_FIELDS = new Set(['external_id', 'source_table', 'source_id', 'source_updated_at', 'cursor']);
const { sanitize } = require('../security/payload-security');

function compact(row, omit = []) {
  const omitted = new Set(omit);
  return sanitize(Object.fromEntries(Object.entries(row).filter(([key, value]) => !HELPER_FIELDS.has(key) && !omitted.has(key) && value !== undefined)));
}

function noNulls(value) {
  if (value === null || value === undefined) return '';
  if (value instanceof Date) return value.toISOString();
  if (Array.isArray(value)) return value.map(noNulls);
  if (typeof value !== 'object') return value;
  return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, noNulls(entry)]));
}

function createNormalizer(defaultEntityType, options = {}) {
  return function normalize(row) {
    const entityType = options.entityType?.(row) || defaultEntityType;
    return {
      entity_type: entityType,
      entity_id: row.external_id || '',
      canonical: noNulls(options.canonical ? sanitize(options.canonical(row)) : compact(row, options.omit)),
      source: {
        system: 'softrestaurant',
        table: row.source_table || '',
        external_id: row.external_id || '',
        source_id: row.source_id || '',
        updated_at: row.source_updated_at || '2000-01-01T00:00:00.000Z',
      },
      metadata: {
        cursor: noNulls(row.cursor || {}),
        scope: options.scope || 'branch',
        ...noNulls(options.metadata ? options.metadata(row) : {}),
      },
    };
  };
}

module.exports = { compact, createNormalizer, noNulls };
