import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types";

export interface SearchOptions {
  recursive?: boolean;
  path?: string[];
  exact?: boolean;
}

export interface SearchInfo {
  field: string;
  value: string;
  exact?: boolean;
}

export interface SearchOperator {
  AND?: (SearchInfo | SearchOperator)[];
  OR?: (SearchInfo | SearchOperator)[];
}

export type Search = SearchOperator & SearchOptions;

export function mapCallback(exact: boolean) {
  const type = ["match", "match_phrase"] as const;
  return (v: SearchInfo | SearchOperator): QueryDslQueryContainer => {
    return "field" in v && "value" in v
      ? { [type[exact || v.exact ? 1 : 0]]: { [v.field]: v.value } }
      : {
          bool: {
            must: v.AND?.map(mapCallback(exact)),
            should: v.OR?.map(mapCallback(exact)),
          },
        };
  };
}
