class SiteSearchController < ApplicationController
  include ActionView::Helpers::TextHelper
  def search
    startTime = Time.now
    if params[:keywords].present?
        modules = [
            {:key=>"announcement", :model=>"Bulletin", :fields=>["title","subtitle","text"], :url=>"/panel/announcement/front_end/bulletin/"}
        ]

        key_string = params[:keywords]
        keywords = key_string.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/)
        regex = Regexp.union(keywords.map{|word| Regexp.new(".*"+word+".*", "i")})

        result = []

        #  Search Pages
        Item.where(:app_frontend_url=>"page_contexts", :is_published=>true).each do |page|
            title = page.title
            context = PageContext.where(:page_id=>page.id).first.context rescue nil
            next if title.nil? and context.nil?

            context = context.gsub(/<\/?[^>]*>/, "").gsub(/&nbsp;/i,"") rescue ""
            title_matches = title.match(regex)
            context_matches = context.match(regex)
            if title_matches or context_matches
                tmp = {}
                tmp[:id] = page.id
                tmp[:module] = "page"
                tmp[:url] = "/"+page.path
                tmp[:title] = title
                tmp[:content] = context
                result.push(tmp)
            end
        end

        #  Search Modules
        modules.each do |mod|
            query = mod[:fields].map{|f| {f.to_sym => regex} }
            res = Kernel.const_get(mod[:model]).any_of(query)
            res.each do |r|
                tmp = {}
                tmp[:id] = r.id
                tmp[:module] = mod[:key]
                tmp[:url] = mod[:url]+r.id.to_s
                tmp[:content] = ""
                tmp[:matches] = 0
                mod[:fields].each do |f|
                    value = eval("r.#{f}").gsub(/<\/?[^>]*>/, "").gsub(/&nbsp;/i,"")

                    if f=="title" or f=="name"
                        tmp[:title] = value
                    else
                        tmp[:content] << value
                    end
                end
                
                result.push(tmp)
            end
        end
    end

    result.each do |res|
        res[:matches] = 0

        res[:matches] += res[:title].match(/(#{key_string})/i) ? 100 : 0 rescue 0
        res[:matches] += res[:content].match(/(#{key_string})/i) ? 100 : 0 rescue 0

        keywords.each do |k|
            res[:matches] += res[:title].scan(/(#{k})/i).size + res[:content].scan(/(#{k})/i).size
            res[:title].gsub!(/(#{k})/i, '<b>\1</b>') rescue ""
            res[:content].gsub!(/(#{k})/i, '<b>\1</b>') rescue ""
        end

        if res[:matches]==0
             result = result - [res]
            next
        end

        res[:content] = truncate(res[:content], length: 150)
    end

    result = result.sort_by { |k| k[:matches] }.reverse rescue []

    render :json => { "results" => result, "time"=> ((Time.now-startTime)*1000).to_i , "keywords"=>keywords}
  end

end