require "test_helper"

class SessionsControllerTest < ActionDispatch::IntegrationTest
  test "should get login page" do
    get login_path
    assert_response :success
    assert_select "h1", "Sign in"
    assert_select "input[type=email]"
    assert_select "input[type=password]"
  end

  test "should redirect to admin if already logged in as admin" do
    login_as(users(:admin_user))
    get login_path
    assert_redirected_to admin_root_path
  end

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

  test "should login with valid credentials" do
    post login_path, params: {
      email: "admin@example.com",
      password: "password123456"
    }

    assert_redirected_to admin_root_path
    assert_equal users(:admin_user).id, session[:user_id]
    follow_redirect!
    assert_select ".bg-green-50", /Welcome back/
  end

  test "should login contributor and redirect to root" do
    post login_path, params: {
      email: "contributor@example.com",
      password: "password123456"
    }

    assert_redirected_to root_path
    assert_equal users(:contributor_user).id, session[:user_id]
  end

  test "should not login with invalid email" do
    post login_path, params: {
      email: "nonexistent@example.com",
      password: "password123456"
    }

    assert_response :unprocessable_entity
    assert_nil session[:user_id]
    assert_select ".bg-red-50", /Invalid email or password/
  end

  test "should not login with invalid password" do
    post login_path, params: {
      email: "admin@example.com",
      password: "wrongpassword"
    }

    assert_response :unprocessable_entity
    assert_nil session[:user_id]
    assert_select ".bg-red-50", /Invalid email or password/
  end

  test "should handle email with whitespace and case insensitivity" do
    post login_path, params: {
      email: "  ADMIN@EXAMPLE.COM  ",
      password: "password123456"
    }

    assert_redirected_to admin_root_path
    assert_equal users(:admin_user).id, session[:user_id]
  end

  test "should not login user with pending invitation" do
    post login_path, params: {
      email: "pending@example.com",
      password: "password123456"
    }

    assert_response :unprocessable_entity
    assert_nil session[:user_id]
    assert_select ".bg-red-50", /Your account is pending/
  end

  test "should logout and redirect to root" do
    login_as(users(:admin_user))

    delete logout_path

    assert_redirected_to root_path
    assert_nil session[:user_id]
    assert_equal "You have been logged out.", flash[:notice]
  end

  test "should logout even when not logged in" do
    delete logout_path

    assert_redirected_to root_path
    assert_nil session[:user_id]
  end
end
