require "test_helper"

class Admin::UsersControllerTest < ActionDispatch::IntegrationTest
  test "should redirect to login when not authenticated" do
    get admin_users_path
    assert_redirected_to login_path
  end

  test "should redirect to root when logged in as non-admin" do
    login_as(users(:contributor_user))
    get admin_users_path
    assert_redirected_to root_path
  end

  test "should show users index when logged in as admin" do
    login_as(users(:admin_user))
    get admin_users_path
    assert_response :success
  end

  test "should filter users by role" do
    login_as(users(:admin_user))

    get admin_users_path, params: { role: "reviewer" }

    assert_response :success
    assert_select "td", text: /#{Regexp.escape(users(:reviewer_user).email)}/
    assert_select "td", text: /#{Regexp.escape(users(:contributor_user).email)}/, count: 0
  end

  test "should filter users by email query" do
    login_as(users(:admin_user))

    get admin_users_path, params: { q: "admin" }

    assert_response :success
    assert_select "td", text: /#{Regexp.escape(users(:admin_user).email)}/
    assert_select "td", text: /#{Regexp.escape(users(:contributor_user).email)}/, count: 0
  end

  test "should get edit page for user when logged in as admin" do
    login_as(users(:admin_user))
    get edit_admin_user_path(users(:contributor_user))
    assert_response :success
  end

  test "should update user role when logged in as admin" do
    login_as(users(:admin_user))

    patch admin_user_path(users(:contributor_user)), params: {
      user: { role: "reviewer" }
    }

    assert_redirected_to admin_users_path
    assert_equal "reviewer", users(:contributor_user).reload.role
  end

  test "should not allow admin to update own role" do
    admin_user = users(:admin_user)
    login_as(admin_user)

    patch admin_user_path(admin_user), params: {
      user: { role: "reviewer" }
    }

    assert_redirected_to admin_users_path
    assert_equal "You cannot modify your own role.", flash[:alert]
    assert_equal "admin", admin_user.reload.role
  end

  test "should ignore invalid role updates" do
    login_as(users(:admin_user))
    contributor = users(:contributor_user)

    patch admin_user_path(contributor), params: {
      user: { role: "invalid_role", name: "Updated Name" }
    }

    assert_redirected_to admin_users_path
    contributor.reload
    assert_equal "contributor", contributor.role
    assert_equal "Updated Name", contributor.name
  end

  test "should render edit when update is invalid" do
    login_as(users(:admin_user))
    contributor = users(:contributor_user)

    patch admin_user_path(contributor), params: {
      user: { email: "" }
    }

    assert_response :unprocessable_entity
    assert_select "li", text: "Email can't be blank"
  end

  test "should delete user when logged in as admin" do
    login_as(users(:admin_user))

    # Delete reviewer_user who has no associated records
    assert_difference("User.count", -1) do
      delete admin_user_path(users(:reviewer_user))
    end

    assert_redirected_to admin_users_path
  end

  test "should not allow admin to delete own account" do
    admin_user = users(:admin_user)
    login_as(admin_user)

    assert_no_difference("User.count") do
      delete admin_user_path(admin_user)
    end

    assert_redirected_to admin_users_path
    assert_equal "You cannot delete your own account.", flash[:alert]
  end

  test "should not allow deleting first admin user" do
    other_admin = User.create!(
      email: "other-admin@example.com",
      name: "Other Admin",
      role: :admin,
      primary_language: "en",
      password: "password123456",
      invitation_accepted_at: Time.current
    )
    login_as(other_admin)

    assert_no_difference("User.count") do
      delete admin_user_path(User.first)
    end

    assert_redirected_to admin_users_path
    assert_equal "Cannot delete the first admin user (system default contact).", flash[:alert]
  end

  test "should not allow non-admin to update user" do
    login_as(users(:contributor_user))

    patch admin_user_path(users(:reviewer_user)), params: {
      user: { role: "admin" }
    }

    assert_redirected_to root_path
  end

  test "should not allow non-admin to delete user" do
    login_as(users(:contributor_user))

    assert_no_difference("User.count") do
      delete admin_user_path(users(:reviewer_user))
    end

    assert_redirected_to root_path
  end
end
