class EpmTrends < EasyPageModule

  OPERATORS = ['>', '-', '+', '/', '*']

  def category_name
    'others'
  end

  def get_query_class(settings, suffix = nil)
    EasyQuery.new_subclass_instance(settings["easy_query_type#{suffix}"]) if settings["easy_query_type#{suffix}"].present?
  end

  def custom_end_buttons?
    false
  end

  def show_preview?
    true
  end

  def collapsible?
    false
  end

  def query_module?
    true
  end

  def get_show_data(settings, user, page_context = {})
    query = get_query(settings, user, page_context)
    return { number_to_show: nil } unless query

    operator = settings['operator']
    use_query_to_compare = settings['use_query_to_compare'].to_boolean

    query_to_compare = get_query_to_compare(query, settings, page_context) if settings['use_query_to_compare'].to_boolean

    show_data = get_data(query, settings, query_to_compare, operator)

    if page_zone_module
      page_zone_module.floating = true
      page_zone_module.css_class = (settings['color'] || 'palette-1') + ' easy-page__module--trend'
    end

    if show_trend?(use_query_to_compare, operator)
      trend_percent = trend_percent(show_data[:number_to_show], show_data[:number_to_compare])
      icon = icon_class(show_data[:trend])
    end

    { number_to_show: show_data[:number_to_show], trend_icon: icon, number_to_compare: show_data[:number_to_compare], trend_percent: trend_percent, operator: operator, formula_tooltip: show_data[:formula_tooltip] }
  end

  def get_edit_data(settings, user, page_context = {})
    query = get_query_class(settings)
    return { query: nil } unless query

    query.project = page_context[:project] if page_context[:project]

    if settings['query_type'] == '2'
      query.from_params(settings['query'])
    end

    query.output = []
    query.export_formats = {}

    query_to_compare = get_query_to_compare(query, settings, page_context) if settings['use_query_to_compare']

    { query: query, query_to_compare: query_to_compare }
  end

  def before_from_params(page_module, params)
    if params && page_module['easy_query_type'] != params['easy_query_type']
      page_module.settings.delete(:query)
      page_module.settings.delete(:query_to_compare)
      page_module.settings.delete(:type)
      page_module.settings.delete(:column_to_sum)
    end
    super
  end

  # Get used queries without applied filters
  # Return Hash where key is query prefix (because of multiple queries)
  def get_all_clean_queries(settings, user, page_context={})
    query = get_query_class(settings)
    query_to_compare = get_query_class(settings, '_to_compare')
    return {} unless query

    if page_context[:project]
      query.project = page_context[:project]
      query_to_compare.project = page_context[:project]
    end

    queries = { 'nil' => query }

    if query_to_compare
      queries['query_to_compare'] = query_to_compare
    end

    queries
  end

  private

  def get_query_to_compare(query, settings, page_context={})
    if !settings['easy_query_type_to_compare'].present?
      query = query.dup
    else
      query = get_query_class(settings, '_to_compare')
      return nil unless query

      query.project = page_context[:project] if page_context[:project]
    end
    set_column_names(query, settings, '_to_compare')
    query.filters = {}
    filters = settings['query_to_compare']
    return query unless filters

    if filters['fields'] && filters['fields'].is_a?(Array)
      filters['values'] ||= {}
      filters['fields'].each do |field|
        query.add_filter(field, filters['operators'][field], filters['values'][field])
      end
    elsif filters['f'].is_a?(Hash)
      filters['f'].each do |field, expression|
        query.add_short_filter(field, expression)
      end
    else
      query.available_filters.keys.each do |field|
        query.add_short_filter(field, filters[field]) if filters[field]
      end
    end

    if query && page_context.has_key?('global_filters') && page_context['global_filters'].has_key?('query_to_compare')
      page_context['global_filters']['query_to_compare'].each do |field, value|
        query.add_short_filter(field, value)
      end
    end

    query
  end

  def get_query(settings, user, page_context={})
    query = get_query_class(settings)
    return nil unless query

    query.project = page_context[:project] if page_context[:project]
    settings.delete('query_id')
    query.from_params(settings['query'])
    query.output = []

    if query && page_context.has_key?('global_filters') && page_context['global_filters'].has_key?('nil')
      page_context['global_filters']['nil'].each do |field, value|
        query.add_short_filter(field, value)
      end
    end
    set_column_names(query, settings)

    query
  end

  def set_column_names(query, settings, suffix= nil)
    if settings["type#{suffix}"] == 'sum' && query.get_column(settings["column_to_sum#{suffix}"])
      query.column_names = [settings["column_to_sum#{suffix}"].try(:to_sym)]
    else
      query.column_names = []
    end
  end

  def get_data(query, settings, query_to_compare = nil, operator = nil)
    query_number = sum_or_count(query, settings)
    if query_to_compare
      query_to_compare_number = sum_or_count(query_to_compare, settings, '_to_compare')
      if show_trend?(true, operator)
        trend = direction_of_trend(query_number, operator, query_to_compare_number)
      else
        result = calculation(query_number, operator, query_to_compare_number)
      end
    end
    formula_tooltip = "#{query_number} #{operator} #{query_to_compare_number}"
    { number_to_show: (result.presence || query_number), trend: trend, number_to_compare: query_to_compare_number, formula_tooltip: formula_tooltip }
  end

  def sum_or_count(query, settings, suffix = nil)
    if settings["type#{suffix}"] == 'sum'
      return nil if query.column_names.empty?
      query.entity_sum(settings["column_to_sum#{suffix}"].to_sym)
    else
      query.entity_count
    end
  end

  def icon_class(trend)
    return 'easy-trend__direction--up' if trend == 1
    return 'easy-trend__direction--down' if trend == -1
    return 'easy-trend__direction--stagnant'
  end

  def calculation(number, operator, second_number)
    calculation_result = nil
    case operator
    when '-'
      calculation_result = number - second_number
    when '+'
      calculation_result = number + second_number
    when '/'
      calculation_result = (number.to_f / second_number.to_f)
    when '*'
      calculation_result = number * second_number
    end
    calculation_result
  end

  def direction_of_trend(number, operator, second_number)
    trend = nil
    case operator
    when '>'
      trend = number <=> second_number
      # when '<'
      #   if number < second_number
      #     trend = 1
      #   elsif number == second_number
      #     trend = 0
      #   else
      #     trend = -1
      #   end
    end
    trend
  end

  def show_trend?(use_query_to_compare, trend_operator)
    return true if use_query_to_compare && trend_operator == '>'
    false
  end

  def trend_percent(number, second_number)
    return 0 if number == second_number
    number.to_f / second_number.to_f * 100
  end

end
