import { canonicalize } from './jsc.js';
const formatGraphQLStringArray = values => `[${values.map(value => JSON.stringify(value)).join(', ')}]`;
const buildValuesListFilter = (spaceSelectionMode, override) => {
  if (!override) {
    if (spaceSelectionMode === 'single') {
      return '(filter: {spaceId: {is: $spaceId}})';
    }
    if (spaceSelectionMode === 'many') {
      return '(filter: {spaceId: {in: $spaceIds}})';
    }
    return '';
  }
  if (override === 'all') {
    return '';
  }
  if (override.length === 0) {
    // Explicit empty overrides should produce a match-nothing filter.
    return '(filter: {spaceId: {in: []}})';
  }
  return `(filter: {spaceId: {in: ${formatGraphQLStringArray(override)}}})`;
};
const buildRelationSpaceFilter = (spaceSelectionMode, override) => {
  if (!override) {
    if (spaceSelectionMode === 'single') {
      return 'spaceId: {is: $spaceId}, ';
    }
    if (spaceSelectionMode === 'many') {
      return 'spaceId: {in: $spaceIds}, ';
    }
    return '';
  }
  if (override === 'all') {
    return '';
  }
  if (override.length === 0) {
    return 'spaceId: {in: []}, ';
  }
  return `spaceId: {in: ${formatGraphQLStringArray(override)}}, `;
};
const sanitizeAliasComponent = value => {
  const collapsed = value.replace(/[^A-Za-z0-9]+/g, '_').replace(/^_+|_+$/g, '');
  return collapsed.length > 0 ? collapsed : 'all';
};
const buildTargetTypeAliasComponent = targetTypeIds => {
  if (!targetTypeIds || targetTypeIds.length === 0) {
    return '';
  }
  const canonicalTypeIds = canonicalize(Array.from(new Set(targetTypeIds)).sort());
  const sanitized = sanitizeAliasComponent(canonicalTypeIds);
  return sanitized.length > 0 ? `_${sanitized}` : '';
};
export const getRelationAlias = (typeId, targetTypeIds) => `relations_${typeId.replace(/-/g, '_')}${buildTargetTypeAliasComponent(targetTypeIds)}`;
const buildRelationTypeIdsFilter = (listField, typeIds) => {
  if (!typeIds || typeIds.length === 0) return '';
  const relationField = listField === 'backlinks' ? 'fromEntity' : 'toEntity';
  return `${relationField}: { typeIds: { in: ${formatGraphQLStringArray(typeIds)} } }, `;
};
const buildRelationsListFragment = (info, level, spaceSelectionMode) => {
  const alias = getRelationAlias(info.typeId, info.targetTypeIds);
  const nestedPlaceholder = info.includeNodes && level === 1 ? '__LEVEL2_RELATIONS__' : '';
  const listField = info.listField ?? 'relations';
  const connectionField = listField === 'backlinks' ? 'backlinks' : 'relations';
  const toEntityField = listField === 'backlinks' ? 'fromEntity' : 'toEntity';
  const toEntitySelectionHeader = toEntityField === 'toEntity' ? 'toEntity' : `toEntity: ${toEntityField}`;
  const valuesListFilter = buildValuesListFilter(spaceSelectionMode, info.valueSpaces);
  const relationSpaceFilter = buildRelationSpaceFilter(spaceSelectionMode, info.relationSpaces);
  const relationEntityTypeFilter = buildRelationTypeIdsFilter(listField, info.targetTypeIds);
  if (!info.includeNodes && !info.includeTotalCount) {
    return '';
  }
  const totalCountSelection = info.includeTotalCount ? `
      totalCount` : '';
  const nodesSelection = info.includeNodes ? `
      nodes {
        id
        entity {
          valuesList${valuesListFilter} {
            propertyId
            string
            boolean
            number
            time
            point
          }
        }
        ${toEntitySelectionHeader} {
          id
          name
          valuesList${valuesListFilter} {
            propertyId
            string
            boolean
            number
            time
            point
          }
          ${nestedPlaceholder}
        }
        typeId
      }` : '';
  return `
    ${alias}: ${connectionField}(
      filter: {${relationSpaceFilter}${relationEntityTypeFilter}typeId: {is: "${info.typeId}"}},
    ) {${totalCountSelection}${nodesSelection}
    }`;
};
const buildLevel2RelationsFragment = (relationInfoLevel2, spaceSelectionMode) => {
  if (relationInfoLevel2.length === 0) return '';
  return relationInfoLevel2.map(info => buildRelationsListFragment(info, 2, spaceSelectionMode)).join('\n');
};
const buildLevel1RelationsFragment = (relationInfoLevel1, spaceSelectionMode) => {
  if (relationInfoLevel1.length === 0) return '';
  return relationInfoLevel1.map(info => {
    const level2Fragment = buildLevel2RelationsFragment(info.children ?? [], spaceSelectionMode);
    const fragment = buildRelationsListFragment(info, 1, spaceSelectionMode);
    return fragment.replace('__LEVEL2_RELATIONS__', level2Fragment);
  }).join('\n');
};
export const buildRelationsSelection = (relationInfoLevel1, spaceSelectionMode) => buildLevel1RelationsFragment(relationInfoLevel1, spaceSelectionMode);
//# sourceMappingURL=relation-query-helpers.js.map