# frozen_string_literal: true

class TopicsFilter
  def self.register_filter(matcher, &block)
    self.filters[matcher] = block
  end

  def self.filters
    @@filters ||= {}
  end

  register_filter(/\Astatus:([a-zA-Z]+)\z/i) do |topics, match|
    case match
    when "open"
      topics.where("NOT topics.closed AND NOT topics.archived")
    when "closed"
      topics.where("topics.closed")
    when "archived"
      topics.where("topics.archived")
    when "deleted"
      if @guardian.can_see_deleted_topics?(@category)
        topics.unscope(where: :deleted_at).where("topics.deleted_at IS NOT NULL")
      end
    end
  end

  def initialize(guardian:, scope: Topic, category_id: nil)
    @guardian = guardian
    @scope = scope
    @category = category_id.present? ? Category.find_by(id: category_id) : nil
  end

  def filter(input)
    input
      .to_s
      .scan(/(([^" \t\n\x0B\f\r]+)?(("[^"]+")?))/)
      .to_a
      .map do |(word, _)|
        next if word.blank?

        self.class.filters.each do |matcher, block|
          cleaned = word.gsub(/["']/, "")

          new_scope = instance_exec(@scope, $1, &block) if cleaned =~ matcher
          @scope = new_scope if !new_scope.nil?
        end
      end

    @scope
  end
end