class PagePartialContext < CmsContext

  def initialize
    super
    @partials = [
      {'name' => 'CTA', 'devs_only' => 'false'},
      {'name' => 'Footer', 'devs_only' => 'true'},
      {'name' => 'Sub Nav Menu - Toggle Visibility', 'devs_only' => 'true'},
      {'name' => 'Nav Menu', 'devs_only' => 'true'},
      {'name' => 'All Fields Mandatory', 'devs_only' => 'true'}
    ]
  end

  def given_partial_not_visible(page)
    page_id = Page.find_by(name: page).id
    page_partial = PagePartial.find_by(page_id: page_id, partial_id: @partial_id)
    page_partial.update!(visible: false)
  end

  def add_partial_to_page(name)
    click_a_tag('Add Partial')
    click_and_wait(name)
    @new_data_index = all('.page-partial').length - 1
  end

  def delete(partial_id = @partial_id)
    @old_order_and_ids = get_order_and_id_hash(PagePartial.where(page_id: @page_id))
    page_partial = PagePartial.find_by(page_id: @page_id, partial_id: partial_id)
    @deleted_order = page_partial.order
    delete_and_wait("#partial-#{page_partial.id}")
  end

  def copy(partial_id = @partial_id)
    within("#partial-#{partial_id}") { find(".copy").click }
    within(".modal-select") { find("li:first-of-type").click }
    wait_for_ajax
  end

  def change_all_fields
    page_partial = PagePartial.find_by(page_id: @page_id, partial_id: @partial_id)
    partial = Partial.find(@partial_id).name
    expand_page_partial("#partial-#{page_partial.id}")
    @field_values, @header_types = {}, {}
    fill_in_all_fields
    click_and_wait('Save')
    @field_values = {"#{partial}" => @field_values}
    sleep(1)
  end

  def change_header_field(fields)
    fields.each do |name, field_type_and_values|
      find("input[data-fieldname='#{name}']").set(field_type_and_values['input'])
      change_nice_select_option(field_type_and_values['select'], find("select[data-fieldname='#{name}']", visible: false))
      @field_values[name] = field_type_and_values['input']
      @header_types[name] = field_type_and_values['select']
    end
  end

  def get_types_and_fields
    get_default_types_and_fields.merge({
      'header' => {
        'Header' => {
          'input' => 'Testing Header',
          'select' => 'Option 2'
        }
      }
    })
  end

  def rearrange(partial, position)
    @page_partial_id = PagePartial.includes(:partial).where(page_id: @page_id).select{|page_partial| page_partial.partial.name == partial}.first.id
    feature_to_move = "#partial-#{@page_partial_id}"
    drag_handle = within(feature_to_move) {find('img.ui-draggable-handle')}
    perform_rearrange(drag_handle, feature_to_move, position)
  end

  def expect_all_page_partials(page_partials)
    page_partials.each do |page_partial|
      expect_content_on_page(page_partial.partial.name)
    end
  end

  def expect_all_pages
    page_partials = PagePartial.where(page_id: @page_id)
    expect_all_page_partials(page_partials)
    expect_page_partials_in_order(page_partials)
  end

  def expect_partial(name)
    partial_id = Partial.find_by(name: name).id
    page_partial = PagePartial.find_by(partial_id: partial_id, page_id: @page_id)
    @page_partial_id = page_partial.id
    expect(page_partial).to be_truthy
    expect_content_on_page(name)
    expect_correct_backend_order
    expect_correct_position_on_screen
  end

  def expect_no_partial(name)
    partial_id = Partial.find_by(name: name).id
    page_partial = PagePartial.find_by(partial_id: partial_id, page_id: @page_id)
    expect(page_partial).to be_falsey
    expect_content_not_on_page(name)
  end

  def expect_updated(partial)
    partial_id = Partial.find_by(name: partial).id
    page_partial = PagePartial.find_by(page_id: @page_id, partial_id: partial_id) || PagePartial.find_by(page_id: nil, partial_id: partial_id)
    expect_field_values_in_database(page_partial, @field_values[partial])
    expect_correct_header_type(page_partial) if @header_types
  end

  def expect_correct_header_type(page_partial)
    expect(page_partial.field_header_styles_hash).to eq(@header_types)
  end

  def expect_correct_backend_order
    expect(PagePartial.find(@page_partial_id).order).to eq(@new_data_index) if @new_data_index
  end

  def expect_correct_data_index
    data_index = find("#partial-#{@page_partial_id}")['data-index']
    expect(data_index).to eq(@new_data_index.to_s)
  end

  def expect_correct_position_on_screen
    if @new_data_index
      all_page_partials = all('.page-partial')
      page_partial = find("#partial-#{@page_partial_id}")
      expect(all_page_partials[@new_data_index]).to eq(page_partial)
    end
  end

  def expect_page_partial_grayed_out
    page_partial = PagePartial.find_by(page_id: @page_id, partial_id: @partial_id)
    expect(find("#partial-#{page_partial.id}")).to have_css('.not-visible')
  end

  def expect_not_visible
    page_partial = PagePartial.find_by(page_id: @page_id, partial_id: @partial_id)
    expect(page).to_not have_selector("section._#{page_partial.id}")
  end

  def expect_order_rearranged
    expect(order_rearranged?(PagePartial.where(page_id: @page_id))).to be_truthy
  end

  private

  def expect_page_partials_in_order(page_partials)
    orders_and_ids = get_order_and_id_hash(page_partials)
    all('.page-partial').each do |page_partial|
      order = page_partial['data-index'].to_i
      id = page_partial['id'].split('-').last.to_i
      expect(id).to eq(orders_and_ids[order])
    end
  end

end
