import { FieldSchema } from '@unito/integration-api';

import { Filter } from './index.js';

/**
 * Use this helper function to retrieve the applicable filters from the context object. While using filters
 * directly from context might work, it doesn't offer any guarantees about the shape of the filters nor the
 * validity of the fields against which the filters are applied. On the other hand, this function ensures that
 * all filters are valid and that the fields against which the filters are applied are present in the schema.
 *
 * @param context The object containing the raw filters
 * @param fields The schema of the item against which the filters are applied
 * @returns The validated filters
 */
export function getApplicableFilters(context: { filters: Filter[] }, fields: FieldSchema[]): Filter[] {
  const applicableFilters: Filter[] = [];

  for (const filter of context.filters) {
    let field: FieldSchema | undefined;

    const filterFieldParts = filter.field.split(':', 2);

    switch (filterFieldParts[0]) {
      case 'semantic':
        field = fields.find(f => f.semantic === filterFieldParts[1]);
        break;
      default:
        field = fields.find(f => f.name === filterFieldParts[0]);
    }

    if (field) {
      applicableFilters.push({ ...filter, field: field.name });
    }
  }

  return applicableFilters;
}

/**
 * Use this helper function to build the query params for a collection next page URL.
 * It re-encodes the parsed filters and selects back into query-param form,
 * so integrations can easily construct `nextPage` URLs.
 *
 * @example
 * const params = buildCollectionQueryParams({ filters: context.filters, selects: context.selects });
 * params.append('cursor', nextCursor);
 * return { info: { nextPage: `/items?${params.toString()}` }, data: [...] };
 */
export function buildCollectionQueryParams(params?: { filters?: Filter[]; selects?: string[] }): URLSearchParams {
  const result = new URLSearchParams();

  if (params?.filters?.length) {
    result.set(
      'filter',
      params.filters.map(f => `${f.field}${f.operator}${(f.values ?? []).map(encodeURIComponent).join('|')}`).join(','),
    );
  }

  if (params?.selects?.length) {
    result.set('select', params.selects.map(encodeURIComponent).join(','));
  }

  return result;
}
