# frozen_string_literal: true

module SearchConfigBuilder
  extend ActiveSupport::Concern

  class_methods do
    def search_highlight_config(query, fields)
      # defines stricter config for highlights to return for search queries.
      # the main thing we're trying to avoid is highlighting words like "the" or "a" in the middle of a sentence.
      # we'll still include those words in the main query using the :word_start option to bias towards returning more results, but we won't highlight them.

      stop_words = [
        "a",
        "about",
        "above",
        "after",
        "again",
        "against",
        "all",
        "am",
        "an",
        "and",
        "any",
        "are",
        "aren't",
        "as",
        "at",
        "be",
        "because",
        "been",
        "before",
        "being",
        "below",
        "between",
        "both",
        "but",
        "by",
        "can't",
        "cannot",
        "could",
        "couldn't",
        "did",
        "didn't",
        "do",
        "does",
        "doesn't",
        "doing",
        "don't",
        "down",
        "during",
        "each",
        "few",
        "for",
        "from",
        "further",
        "had",
        "hadn't",
        "has",
        "hasn't",
        "have",
        "haven't",
        "having",
        "he",
        "he'd",
        "he'll",
        "he's",
        "her",
        "here",
        "here's",
        "hers",
        "herself",
        "him",
        "himself",
        "his",
        "how",
        "how's",
        "i",
        "i'd",
        "i'll",
        "i'm",
        "i've",
        "if",
        "in",
        "into",
        "is",
        "isn't",
        "it",
        "it's",
        "its",
        "itself",
        "let's",
        "me",
        "more",
        "most",
        "mustn't",
        "my",
        "myself",
        "no",
        "nor",
        "not",
        "of",
        "off",
        "on",
        "once",
        "only",
        "or",
        "other",
        "ought",
        "our",
        "ours",
        "ourselves",
        "out",
        "over",
        "own",
        "same",
        "shan't",
        "she",
        "she'd",
        "she'll",
        "she's",
        "should",
        "shouldn't",
        "so",
        "some",
        "such",
        "than",
        "that",
        "that's",
        "the",
        "their",
        "theirs",
        "them",
        "themselves",
        "then",
        "there",
        "there's",
        "these",
        "they",
        "they'd",
        "they'll",
        "they're",
        "they've",
        "this",
        "those",
        "through",
        "to",
        "too",
        "under",
        "until",
        "up",
        "very",
        "was",
        "wasn't",
        "we",
        "we'd",
        "we'll",
        "we're",
        "we've",
        "were",
        "weren't",
        "what",
        "what's",
        "when",
        "when's",
        "where",
        "where's",
        "which",
        "while",
        "who",
        "who's",
        "whom",
        "why",
        "why's",
        "with",
        "won't",
        "would",
        "wouldn't",
        "you",
        "you'd",
        "you'll",
        "you're",
        "you've",
        "your",
        "yours",
        "yourself",
        "yourselves",
      ]
      min_highlight_word_length = 3

      query_without_stop_words = query.split(" ").reject { |word| stop_words.include?(word) || word.length < min_highlight_word_length }.join(" ")

      {
        order: "score",
        pre_tags: ["<span class='search-highlight'>"],
        post_tags: ["</span>"],
        encoder: "html",
        fields: fields.each_with_object({}) do |field, hash|
          hash["#{field}.analyzed"] = {
            fragment_size: field == :title ? 300 : 100,
            number_of_fragments: 1,
          }
        end,
        highlight_query: {
          bool: {
            should: fields.flat_map do |field|
              [
                { match_phrase: { "#{field}.analyzed": { query: query, boost: 3 } } },
                { match: { "#{field}.analyzed": { query: query_without_stop_words } } },
              ]
            end,
          },
        },
      }
    end
  end
end
