# frozen_string_literal: true
class MainController < ApplicationController
  include TopicsHelper
  include MapsHelper
  include UsersHelper
  include SynapsesHelper

  after_action :verify_policy_scoped, except: [:requestinvite, :searchmappers]

  respond_to :html, :json

  # home page
  def home
    @maps = policy_scope(Map).order('updated_at DESC').page(1).per(20)
    respond_to do |format|
      format.html do
        if !authenticated?
          render 'main/home'
        else
          render 'maps/activemaps'
        end
      end
    end
  end

  ### SEARCHING ###

  # get /search/topics?term=SOMETERM
  def searchtopics
    term = params[:term]
    user = params[:user] ? params[:user] : false

    if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?

      # remove "topic:" if appended at beginning
      term = term[6..-1] if term.downcase[0..5] == 'topic:'

      # if desc: search desc instead
      desc = false
      if term.downcase[0..4] == 'desc:'
        term = term[5..-1]
        desc = true
      end

      # if link: search link instead
      link = false
      if term.downcase[0..4] == 'link:'
        term = term[5..-1]
        link = true
      end

      # check whether there's a filter by metacode as part of the query
      filterByMetacode = false
      Metacode.all.each do |m|
        lOne = m.name.length + 1
        lTwo = m.name.length

        if term.downcase[0..lTwo] == m.name.downcase + ':'
          term = term[lOne..-1]
          filterByMetacode = m
        end
      end

      search = '%' + term.downcase + '%'
      builder = policy_scope(Topic)

      if filterByMetacode
        if term == ''
          builder = builder.none
        else
          builder = builder.where('LOWER("name") like ? OR
                                   LOWER("desc") like ? OR
                                   LOWER("link") like ?', search, search, search)
          builder = builder.where(metacode_id: filterByMetacode.id)
        end
      elsif desc
        builder = builder.where('LOWER("desc") like ?', search)
      elsif link
        builder = builder.where('LOWER("link") like ?', search)
      else # regular case, just search the name
        builder = builder.where('LOWER("name") like ? OR
                                 LOWER("desc") like ? OR
                                 LOWER("link") like ?', search, search, search)
      end

      builder = builder.where(user: user) if user
      @topics = builder.order(:name)
    else
      @topics = []
    end

    render json: autocomplete_array_json(@topics)
  end

  # get /search/maps?term=SOMETERM
  def searchmaps
    term = params[:term]
    user = params[:user] ? params[:user] : nil

    if term && !term.empty? && term.downcase[0..5] != 'topic:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero?

      # remove "map:" if appended at beginning
      term = term[4..-1] if term.downcase[0..3] == 'map:'

      # if desc: search desc instead
      desc = false
      if term.downcase[0..4] == 'desc:'
        term = term[5..-1]
        desc = true
      end

      search = '%' + term.downcase + '%'
      builder = policy_scope(Map)

      builder = if desc
                  builder.where('LOWER("desc") like ?', search)
                else
                  builder.where('LOWER("name") like ?', search)
                end
      builder = builder.where(user: user) if user
      @maps = builder.order(:name)
    else
      @maps = []
    end

    render json: autocomplete_map_array_json(@maps)
  end

  # get /search/mappers?term=SOMETERM
  def searchmappers
    term = params[:term]
    if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?

      # remove "mapper:" if appended at beginning
      term = term[7..-1] if term.downcase[0..6] == 'mapper:'
      search = term.downcase + '%'

      skip_policy_scope # TODO: builder = policy_scope(User)
      builder = User.where('LOWER("name") like ?', search)
      @mappers = builder.order(:name)
    else
      @mappers = []
    end
    render json: autocomplete_user_array_json(@mappers)
  end

  # get /search/synapses?term=SOMETERM OR
  # get /search/synapses?topic1id=SOMEID&topic2id=SOMEID
  def searchsynapses
    term = params[:term]
    topic1id = params[:topic1id]
    topic2id = params[:topic2id]

    if term && !term.empty?
      @synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase + '%').order('"desc"')

      @synapses = @synapses.uniq(&:desc)
    elsif topic1id && !topic1id.empty?
      @one = policy_scope(Synapse).where('node1_id = ? AND node2_id = ?', topic1id, topic2id)
      @two = policy_scope(Synapse).where('node2_id = ? AND node1_id = ?', topic1id, topic2id)
      @synapses = @one + @two
      @synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
    else
      @synapses = []
    end

    # limit to 5 results
    @synapses = @synapses.to_a.slice(0, 5)

    render json: autocomplete_synapse_array_json(@synapses)
  end
end
