import { Graph } from '@graphprotocol/grc-20';
import { Constants } from '@graphprotocol/hypergraph';
import * as Option from 'effect/Option';
import * as SchemaAST from 'effect/SchemaAST';
/**
 * Translates internal filter format to GraphQL filter format
 * Maps the internal EntityFieldFilter structure to the expected GraphQL filter structure
 */
export function translateFilterToGraphql(filter, type) {
  if (!filter) {
    return {};
  }
  const graphqlFilter = [];
  const buildRelationExistsFilter = propertyId => ({
    relations: {
      some: {
        typeId: {
          is: propertyId
        }
      }
    }
  });
  for (const [fieldName, fieldFilter] of Object.entries(filter)) {
    if (fieldName === 'or') {
      graphqlFilter.push({
        or: fieldFilter.map(filter => translateFilterToGraphql(filter, type))
      });
      continue;
    }
    if (fieldName === 'not') {
      graphqlFilter.push({
        not: translateFilterToGraphql(fieldFilter, type)
      });
      continue;
    }
    if (!fieldFilter) continue;
    if (fieldName === 'id') {
      const idFilter = fieldFilter;
      if (typeof idFilter.is === 'string') {
        graphqlFilter.push({
          id: {
            is: idFilter.is
          }
        });
      }
      continue;
    }
    const ast = type.ast;
    const propertySignature = ast.propertySignatures.find(a => a.name === fieldName);
    if (!propertySignature) continue;
    // find the property id for the field
    const propertyId = SchemaAST.getAnnotation(Constants.PropertyIdSymbol)(propertySignature.type);
    const propertyType = SchemaAST.getAnnotation(Constants.PropertyTypeSymbol)(propertySignature.type);
    if (!Option.isSome(propertyId) || !Option.isSome(propertyType)) continue;
    if (propertyType.value === 'relation') {
      const relationFilter = fieldFilter;
      if (relationFilter.exists === true) {
        graphqlFilter.push(buildRelationExistsFilter(propertyId.value));
        continue;
      }
      if (relationFilter.exists === false) {
        const existsFilter = buildRelationExistsFilter(propertyId.value);
        graphqlFilter.push({
          not: existsFilter
        });
        continue;
      }
    }
    if (propertyType.value === 'string' && (fieldFilter.is || fieldFilter.startsWith || fieldFilter.endsWith || fieldFilter.contains)) {
      graphqlFilter.push({
        values: {
          some: {
            propertyId: {
              is: propertyId.value
            },
            string: fieldFilter.is ? {
              is: fieldFilter.is
            } : fieldFilter.startsWith ? {
              startsWith: fieldFilter.startsWith
            } : fieldFilter.endsWith ? {
              endsWith: fieldFilter.endsWith
            } : {
              includes: fieldFilter.contains
            }
          }
        }
      });
    }
    if (propertyType.value === 'boolean' && fieldFilter.is) {
      graphqlFilter.push({
        values: {
          some: {
            propertyId: {
              is: propertyId.value
            },
            boolean: {
              is: fieldFilter.is
            }
          }
        }
      });
    }
    if (propertyType.value === 'number' && (fieldFilter.is || fieldFilter.greaterThan || fieldFilter.lessThan)) {
      graphqlFilter.push({
        values: {
          some: {
            propertyId: {
              is: propertyId.value
            },
            number: fieldFilter.is ? {
              is: Graph.serializeNumber(fieldFilter.is)
            } : fieldFilter.greaterThan ? {
              greaterThan: Graph.serializeNumber(fieldFilter.greaterThan)
            } : {
              lessThan: Graph.serializeNumber(fieldFilter.lessThan)
            }
          }
        }
      });
    }
  }
  if (graphqlFilter.length === 1) {
    return graphqlFilter[0];
  }
  return {
    and: graphqlFilter
  };
}
//# sourceMappingURL=translate-filter-to-graphql.js.map