module EasyButtons
  class QueryBase

    attr_reader :key, :options, :definition, :query

    def initialize(key, options, definition, query)
      @key = key
      @options = options
      @definition = definition
      @query = query
    end

    def self.parse(query, definitions)
      result = []
      definitions = Hash[definitions] if definitions.is_a?(Array)

      query.filters.each do |key, options|
        definition = definitions[key]

        # Filter does not have 'attr_reader' or 'attr_writer' option
        next if definition.nil?

        result << self.new(key, options, definition, query).parse
      end

      result.compact!
      result
    end

    def parse
      case type
      when :list
        create_list
      when :list_status
        create_list_status
      when :list_optional
        create_list_optional
      when :list_autocomplete
        create_list_autocomplete
      when :float
        create_float
      when :integer
        create_integer
      when :string
        create_string
      when :text
        create_string
      when :boolean
        create_boolean
      else
        raise "EasyActionButton: Type #{type} is not supported."
      end
    end

    def create_list; end
    def create_list_status; end
    def create_list_optional; end
    def create_float; end
    def create_integer; end
    def create_string; end
    def create_boolean; end
    def create_list_autocomplete; end

    def possible_values
      definition[:values]
    end

    def type
      definition[:type]
    end

    def values
      options[:values]
    end

    def values_as_int
      @values_as_int ||= values.map(&:to_i)
    end

    def values_as_float
      @values_as_float ||= values.map(&:to_f)
    end

    def values_as_string
      return @values_as_string if @values_as_string

      @values_as_string = options[:values].to_s

      if query.columns_with_me.include?(key) || (definition[:field] && definition[:field].format.target_class && definition[:field].format.target_class <= User)
        @values_as_string.gsub!('"me"', 'User.current.id.to_s')
      end

      @values_as_string
    end

    def operator
      options[:operator]
    end

    def key_without_id
      @key_without_id ||= @key.gsub(/\_id$/, '')
    end

    def cf
      @cf ||= key.match(/((\w*)_)?cf_(\d+)/)
    end

    def cf?
      !!cf
    end

    def cf_id
      cf && cf[3].to_i
    end

    def cf_entity
      cf && cf[2]
    end

    def get_value
      if cf?
        if cf_entity
          "entity.#{cf_entity} && entity.#{cf_entity}.custom_field_value(#{cf_id})"
        else
          "entity.custom_field_value(#{cf_id})"
        end
      else
        "entity.#{key}"
      end
    end

    def checking_id?
      @checking_id ||= possible_values.first.is_a?(Array) ? true : false
    end

  end
end
