class EasyEntityCustomAttribute < EasyEntityAttribute

  attr_reader :custom_field

  def initialize(custom_field, options={})
    super("cf_#{custom_field.id}".to_sym, options)
    @custom_field = custom_field
    @numeric = custom_field.format.numeric?(custom_field)
    @preload = options[:assoc] ? {options[:assoc] => :custom_values} : :custom_values
  end

  def caption(with_suffixes=false)
    @custom_field.translated_name
  end

  def value_object(entity, options={})
    return nil if entity.nil?

    entity = entity.send(assoc) if assoc

    return nil if entity.nil? || !entity.respond_to?(:custom_values)

    if @custom_field && @custom_field.visible_on?(entity, User.current)
      cv = entity.custom_values.select {|v| v.custom_field_id == @custom_field.id}
      cv.size > 1 ? cv.sort {|a,b| a.value.to_s <=> b.value.to_s} : cv.first
    else
      nil
    end
  end

  def value(entity, options={})
    raw = value_object(entity, options)
    if raw.is_a?(Array)
      raw.map {|r| @custom_field.cast_value(r.value)}
    elsif raw
      @custom_field.cast_value(raw.value)
    else
      nil
    end
  end

  def custom_value_of(entity)
    if assoc
      entity = entity.send(assoc)
      return nil if !entity.respond_to?(:custom_value_for)
    end
    entity.custom_value_for(@custom_field)
  end

  def css_classes
    @css_classes ||= [super, @custom_field.field_format.to_s.underscore].reject(&:blank?).join(' ')
  end

end

module EasyEntityCustomAttributeColumnExtensions

  def self.included(base)
    base.send(:include, EasySumableAttributeColumnExtension)
    base.send(:include, InstanceMethods)
  end

  attr_accessor :sortable, :groupable, :default_order

  def initialize(custom_field, options={})
    super(custom_field, options)
    self.sortable = custom_field.order_statement || nil
    self.groupable = custom_field.group_statement || false
    @inline = true
    if custom_field.summable?
      self.sumable ||= :both
      self.sumable_sql ||= custom_field.summable_sql
      if assoc && !sumable_options.distinct_columns?
        self.sumable_options = {distinct_columns: "#{@assoc}_id"}
      end
    end
  end

  def sortable?
    !sortable.nil?
  end

  module InstanceMethods
    def additional_joins(entity_class, type=:sql, uniq=false)
      result = super(entity_class, type).dup

      case type
      when :sql
        association = entity_class.reflect_on_all_associations(:belongs_to).detect{|as| as.name == assoc}
        result << "INNER JOIN #{association.klass.table_name} ON #{association.klass.table_name}.id = #{entity_class.table_name}.#{association.foreign_key}" if association
      when :array
        result << assoc
      end if assoc

      join_statement = custom_field.format.join_for_order_statement(custom_field, uniq)

      result << join_statement if join_statement

      result
    end
  end
end
