class UserContext < CmsContext
  def get_user_information
    {
      'Madeline' => {
        'email' => 'madeline@teachable.com',
        'password' => 'password',
        'team_id' => 'Operations',
        'permission_id' => 'User',
      }
    }
  end

  def given_user_with_a_blog_post(author_name)
    author = User.find_by(name: author_name)
    profile_pic = Upload.create!(
      category: "user",
      upload_type: "image",
      uploaded_by: 1,
      url: "https://cdn.filepicker.io/api/file/kCve4yn2SueImwKdMnyG",
    )
    author.update(image_id: profile_pic.id)

    BlogPost.create!(
      title: "#{author_name}'s Blog Post",
      title_text: "#{author_name}'s Blog Post",
      date: nil,
      author: author,
      url: "/test-blog-post",
      canonical_url: "https://teachable.com/blog/test-blog-post"
    )
  end

  def create_permissions
    ['Super administrator','Administrator', 'User', 'No access'].each do |permission|
      Permission.find_by(name: permission) || create_permission(permission)
    end
  end

  def create_teams
    ['Growth', 'Customer care', 'Engineering', 'Executive', 'Operations'].each do |team|
      Team.find_by(name: team) || Team.create!(name: team)
    end
  end

  def create_user(name, valid_or_invalid)
    within('#new-entity') do
      fill_in_row(get_user_information[name].merge({'name' => name})) if valid_or_invalid == 'valid'
      click_and_wait('Add User')
    end
  end

  def create_permissions_and_permission_privileges
    create_permissions
    create_privileges
    create_permission_privileges
  end

  def delete_user(name)
    User.find_by(name: name).destroy
  end

  def open_permissions
    path = find_by_data_field('permissionId').path
    within(:xpath, get_ancestor_path(path)) do
      find('div.nice-select').click
    end
  end

  def change_attribute(attribute, new_value)
    field = find_by_data_field(make_lazy_camel_case(attribute))
    @new_value, @old_value = new_value, field.value
    field.set(new_value)
    click_and_wait('Save')
  end

  def expect_user_in_database(user_instance, name)
    user_information = get_user_information[name].merge({'name' => name})
    user_information.each do |column, value|
      next if column == 'password'
      if column == 'team_id'
        value = Team.find_by(name: value).id
      elsif column == 'permission_id'
        value = Permission.find_by(name: value).id
      end
      expect(user_instance[column.to_sym]).to eq(value)
    end
  end

  def expect_correct_permissions
    within('#new-entity') do
      ['Administrator', 'Super Administrator'].each { |name| expect_content_not_on_page(name) }
    end
  end

  def expect_all
    index_values = get_index_values
    User.all.each do |user|
      expect_in_index(user, index_values)
    end
  end

  def expect_alphabetized
    names = all('.name-column').map {|name_column| name_column.text}
    expect_sorted_text(names)
  end

  def expect_in_index(user, index_values = get_index_values)
    db_user_info = get_values_array(user)
    expect(field_values_in_index?(db_user_info, index_values)).to be true
  end

  def expect_correct_privileges
    user_privileges = User.find_by(name: @current_user).privileges.map {|privilege| privilege.name}
    Privilege.all.each do |privilege|
      text = privilege.name
      if user_privileges.include?(text)
        expect_content_on_page(text)
      else
        expect_content_not_on_page(text)
      end
    end
  end

  def expect_user_not_in_database(name)
    expect User.find_by(name: name).nil?
  end

  def expect_blog_post_to_be_guest_authored(name)
    post = BlogPost.includes(:author).select { |bp| bp.author_info[:name] == name }[0]
    has_valid_backend = post.author_type == "Objekt"

    visit("/admin/blog_posts/#{post.id}")
    has_valid_frontend = page.has_content?("#{name} (Guest Author)")

    expect has_valid_backend && has_valid_frontend
  end

  private

  def create_privileges
    ["Update your name, email, and title", "Update your team", "Add/edit/delete users", "Add/edit/delete administrators", "Add/edit/delete super administrators"].each do |privilege|
      Privilege.find_by(name: privilege) || Privilege.create(name: privilege)
    end
  end

  def create_permission_privileges
    permissions_and_last_privilege_id = {"User" => 1, "Administrator" => 3, "Super administrator" => 5}
    permissions_and_last_privilege_id.each do |permission, last_privilege_id|
      permission_id = Permission.find_by(name: permission).id
      (1..last_privilege_id).each do |privilege_id|
        PermissionPrivilege.create!(permission_id: permission_id, privilege_id: privilege_id)
      end
    end
  end

  def get_values_array(user)
    values = []
    skip_columns = ['id', 'created_at', 'updated_at', 'email', 'encrypted_password', 'confirmation_token', 'remember_token', 'bio']
    User.column_names.each do |column_name|
      values << convert_to_front_end_format(column_name, user[column_name]) unless skip_columns.include?(column_name)
    end
    values
  end

  def convert_to_front_end_format(column, value)
    case column
    when 'permission_id'
      Permission.find(value).name
    when 'team_id'
      Team.find(value).name
    when 'image_id'
      if value.nil?
        "assets/admin/default-user-image-c533c1a90b2ab781b3108bc1c20a327c7c4ea022ebf5ad767a85c01b9f0362eb.jpg"
      else
        Upload.find(user['image_id']).url
      end
    else
      value
    end
  end

  def get_index_values
    within('.admin-table') do
      all('tr').map do |row|
        row_values = []
        within(row) do
          all('td').each do |column|
            if column[:class] == 'name-column'
              row_values << find('img')[:src].split('/')[3..-1].join('/')
            end
            row_values << column.text
          end
        end
        row_values
      end
    end
  end
end
