class EpmEasyQueryBase < EasyPageModule

  def query_class
    raise "please define a #{self.class.name}#query_class method"
  end

  # better than redefine query_class method everywhere
  def get_query_class(_settings)
    query_class
  end

  def show_path
    'easy_page_modules/easy_query_show'
  end

  def edit_path
    'easy_page_modules/easy_query_edit'
  end

  def custom_end_buttons?
    false
  end

  def show_preview?
    true
  end

  # redefine page_module method - that should be deleted
  def output(settings)
    settings['outputs'].is_a?(Array) ? settings['outputs'].first : settings['output']
  end

  def get_show_data(settings, user, page_context = {})
    query = get_query(settings, user, page_context)

    if page_zone_module && query
      case output(settings)
      when 'chart'
        # page_zone_module.floating = true
      when 'calendar'
        calendar = query.build_calendar(user: user, start_date: (settings['start_date'].to_date rescue nil), period: settings['period'])
      else
        entities = get_entities(query, settings)
      end
    end

    { query: query, entities: entities, calendar: calendar}
  end

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

    query = query_klass.new(:name => settings['query_name'] || '')
    query.project = page_context[:project] if page_context[:project]

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

    query.output = output(settings) || 'list'
    query.export_formats = {}

    { query: query }
  end

  def page_module_toggling_container_options_helper_method
    'get_epm_easy_query_base_toggling_container_options'
  end

  def before_from_params(page_module, params)
    @default_output = output(page_module.settings)
  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_klass = get_query_class(settings)
    return {} unless query_klass

    if settings['query_type'] == '2'
      query = query_klass.new(name: settings['query_name'])
    elsif settings['query_id'].present?
      query = query_klass.find_by(id: settings['query_id'])
    end

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

    if query
      { 'nil' => query }
    else
      {}
    end
  end

  protected

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

    if page_context.has_key?('global_filters') && page_context['global_filters'].has_key?('nil')
      settings['additional_filters'] = page_context['global_filters']['nil']
    end

    if settings['query_type'] == '2'
      query = query_klass.new(:name => settings['query_name'])
      query.project = page_context[:project] if page_context[:project]
      settings.delete('query_id')
      query.from_params(settings)
      query.output = output(settings) || 'list'
    elsif settings['query_id'].present?
      begin
        query = query_klass.find(settings['query_id'])
        query.project = page_context[:project] if page_context[:project]
        query.set_additional_params(settings)
        query.set_sort_params(settings)
      rescue ActiveRecord::RecordNotFound
      end
    end

    if query && @default_output
      outputs = RedmineExtensions::EasyQueryHelpers::Outputs.new(query)
      def_output = outputs.available_outputs.detect{|o| o.key == @default_output}
      def_output.apply_settings if def_output
      outputs.each{|o| o.configure_from_defaults unless o.key == @default_output }
    end

    query
  end

  def get_entities(query, settings)
    row_limit = settings['row_limit'].blank? ? 10 : settings['row_limit'].to_i
    options = {limit: (row_limit > 0 ? row_limit : nil)}.merge(settings[:query_options].to_h)

    if query.grouped? && self.output(settings) != 'calendar'
      query.groups(options)
    else
      query.entities(options)
    end
  end

end
