class EasyEntityActivityQuery < EasyQuery

  def initialize_available_columns
    group = l("label_filter_group_#{self.class.name.underscore}")
    add_available_column EasyQueryDateColumn.new(:start_time, :title => EasyEntityActivity.human_attribute_name(:start_time), :sortable => "#{EasyEntityActivity.table_name}.start_time", :groupable => "#{EasyEntityActivity.table_name}.start_time", :group => group)
    add_available_column EasyQueryColumn.new(:easy_entity_activity_attendees, :title => EasyEntityActivity.human_attribute_name(:attendees), :group => group, :includes => [:easy_entity_activity_attendees], groupable: "COALESCE(CONCAT(#{EasyEntityActivityAttendee.table_name}.entity_type, '_', #{EasyEntityActivityAttendee.table_name}.entity_id), '_')")
    add_available_column EasyQueryColumn.new(:author, :title => EasyEntityActivity.human_attribute_name(:author_id), :sortable => lambda { User.fields_for_order_statement('authors') }, :groupable => "#{EasyEntityActivity.table_name}.author_id", :preload => [:author], :group => group)
    add_available_column EasyQueryColumn.new(:category, :title => EasyEntityActivity.human_attribute_name(:category), :group => group, :preload => [:category] , :groupable => "#{EasyEntityActivity.table_name}.category_id" )
    add_available_column EasyQueryColumn.new(:description, :title => EasyEntityActivity.human_attribute_name(:description), :inline => false, :group => group)
    add_available_column EasyQueryColumn.new(:is_finished, :title => EasyEntityActivity.human_attribute_name(:is_finished), :group => group)
    add_available_column EasyQueryColumn.new(:entity, :title => EasyEntityActivity.human_attribute_name(:entity), :groupable => "#{EasyEntityActivity.table_name}.entity_id", :group => group, :preload => [:entity])
  end

  def initialize_available_filters
    group = l("label_filter_group_#{self.class.name.underscore}")
    add_available_filter 'author_id', {:type => :list, :order => 4, :values => Proc.new { all_users_values(:include_me => true) },
                                       :group => group, :name => EasyEntityActivity.human_attribute_name(:author_id)}
    add_available_filter 'easy_entity_activity_attendees', {:type => :list_autocomplete, source: 'easy_entity_activity_attendees', :most_used => true, :order => 5, :group => group, :name => EasyEntityActivity.human_attribute_name(:attendees)}
    add_available_filter 'created_at', {:type => :date_period, :time_column => true, :order => 15, :group => group}
    add_available_filter 'updated_at', {:type => :date_period, :time_column => true, :label => :label_updated_within, :group => group}
    add_available_filter 'is_finished', {:type => :boolean, :order => 11, :group => group, :name => EasyEntityActivity.human_attribute_name(:is_finished), :attr_reader => true, :attr_writer => true}
    add_available_filter 'description', {:type => :text, :order => 14, :group => group, :name => EasyEntityActivity.human_attribute_name(:description)}
    add_available_filter 'category_id', {:type => :list, :order => 2, :values => Proc.new {EasyEntityActivityCategory.sorted.collect { |s| [s.name, s.id.to_s] }},
                                         :group => group, :name => EasyEntityActivity.human_attribute_name(:category_id)
    }
    add_available_filter 'start_time', {type: :date_period, time_column: true, order: 20, group: group, name: EasyEntityActivity.human_attribute_name(:start_time)}
    add_available_filter 'entity_type', {:type => :list, :order => 3, :values => -> { EasyEntityActivity.uniq.pluck(:entity_type).collect{|type| [l("label_#{type.underscore}"), type]}
    }, :group => group, :name => l(:field_entity_type)}
  end

  def entity
    EasyEntityActivity
  end

  def default_list_columns
    super.presence || ['entity','category', 'start_time', 'easy_entity_activity_attendees', 'author', 'description']
  end

  def calendar_support?
    true
  end

  def sql_for_easy_entity_activity_attendees_field(field, operator, value)
    db_table = EasyEntityActivityAttendee.table_name
    val = Array.wrap(value)
    condition = ''
    if !val.first.blank?
      if val.delete('me')
        val << "Principal_#{User.current.id}"
      end
      val = val.select {|x| x['_']}
      unless val.empty?
        condition << ' AND ('
        condition << val.map{|v| v.split('_')}.map {|f| "(#{db_table}.entity_type = '#{f[0]}' AND #{db_table}.entity_id = #{f[1]})"}.join(' OR ')
        condition << ')'
      end
    end
    "#{operator.to_s.start_with?('!') ? 'NOT ' : ''}EXISTS (SELECT 1 FROM #{db_table} where #{db_table}.easy_entity_activity_id = #{EasyEntityActivity.table_name}.id#{condition})"
  end

  def add_additional_order_statement_joins(order_options)
    joins = []
    if order_options
      if order_options.include?('authors')
        joins << "LEFT OUTER JOIN #{User.table_name} authors ON authors.id = #{entity_table_name}.author_id"
      end
    end
    joins
  end

  def objects_for(field, klass = nil, filters=self.filters)
    if field == 'easy_entity_activity_attendees'
      field_ids = values_for(field)
      objects = []
      struct = Struct.new(:id, :to_s)
      begin
        field_ids.map {|x| x.split('_')}.group_by {|split| split[0]}.each do |klass, ids|
          objects_raw = klass.constantize.where(id: ids)
          objects_raw.each do |object|
            objects << struct.new("#{object.class.base_class}_#{object.id}", object.to_s)
          end
        end
      rescue
        nil
      end
      objects
    else
      super
    end
  end
end
