class ObjektContext < CmsContext

  include ContentDataSetup

  def given_page_with_all_objekts(name)
    @template_id = Template.find_by(name: name).id
    visit "admin/templates/#{@template_id}/all#{get_params}"
  end

  def given_on_edit_page
    visit "admin/objects/#{@objekt_id}#{get_params}"
  end

  def given_an_objekt(template, field_name, value)
    @template_id = Template.find_by(name: template).id
    template_field_id = Field.find_by(template_id: @template_id, name: field_name).id
    @objekt_id = Objekt.all.select do |objekt|
      @objekt_field_id = objekt.fields.select {|field| field.value == value && field.field_id == template_field_id}.first.id
    end.first.id
  end

  def create_objekt
    @field_values = {}
    template = Template.find(@template_id)
    click_a_tag("Add New")
    fill_in_all_fields
    save
  end

  def change_field(name, text)
    @field_values = Objekt.find(@objekt_id).field_values_hash
    @old_value = @field_values[name]
    @field_values[name] = text
    fill_in_by_data_field(@objekt_field_id, text)
    click_and_wait("Save")
  end

  def delete
    @field_values = Objekt.find(@objekt_id).field_values_hash
    click_a_tag('Delete')
    within('.confirm-delete') { click_and_wait('Yes') }
  end

  def save
    within('#object-new') { click_and_wait("Add #{Template.find(@template_id).name}") }
  end

  def expect_objekts_on_page
    index_values = get_objekt_index_values
    Objekt.where(template_id: @template_id).each do |objekt|
      expect_in_index(true, objekt, index_values)
    end
  end

  def expect_in_index(is_in_index, db_objekt = nil, index_values = get_objekt_index_values)
    values_in_database = (@field_values || db_objekt.field_values_hash).values
    front_end_formated_values = front_end_formated_values(values_in_database)
    expect(field_values_in_index?(front_end_formated_values, index_values)).to be is_in_index
  end

  def expect_updated
    objekt = Objekt.find(@objekt_id)
    expect_field_values_in_database(objekt)
  end

  def expect_field_not_changed(field)
    field_values = Objekt.find(@objekt_id).field_values_hash
    expect(field_values[field]).to eq(@old_value)
  end

  def expect_not_to_exist
    expect(Objekt.find_by(id: @objekt_id)).to be_falsey
    expect_in_index(false)
  end

  def expect_correct_mandatory_errors
    field_types_with_defaults = ['color', 'dropdown', 'object']
    Template.find(@template_id).fields.each do |field|
      error = "#{field.name.capitalize} is mandatory"
      field_types_with_defaults.include?(field.field_type) ? expect_content_not_on_page(error) : expect_content_on_page(error)
    end
  end

  private

  def front_end_formated_values(field_values)
    field_values[0...6].map do |value|
      value.length > 30 ? "#{value.slice(0, 30)}..." : value
    end
  end

  def get_objekt_index_values
    within('table') do
      all('tr').map do |current_tr|
        within(current_tr) do
          all('td').map do |td|
            text = td.text
            text.empty? ? get_image_id(td) : text
          end
        end
      end
    end
  end

  def get_image_id(capybara_node)
    within(capybara_node) do
      begin
        src = all('img', visible: false).first['src']
        Upload.find_by(url: src).id.to_s
      rescue
        ""
      end
    end
  end

  def get_types_and_fields
    get_default_types_and_fields
  end
end
