defmodule MvWeb.UserLive.FormMemberDropdownTest do
  @moduledoc """
  UI tests for member linking dropdown visibility and email handling.
  Tests dropdown behavior, visibility states, and email conflict scenarios.
  Related to Issue #168.
  """

  use MvWeb.ConnCase, async: true

  import Phoenix.LiveViewTest

  alias Mv.Membership

  # Helper to setup authenticated connection for admin
  defp setup_admin_conn(conn) do
    conn_with_oidc_user(conn, %{email: "admin@example.com"})
  end

  describe "dropdown visibility" do
    test "dropdown hidden on mount", %{conn: conn} do
      conn = setup_admin_conn(conn)
      {:ok, _view, html} = live(conn, ~p"/users/new")

      # Dropdown should not be visible initially
      refute html =~ ~r/role="listbox"/
    end

    test "dropdown shows after focus event", %{conn: conn} do
      conn = setup_admin_conn(conn)
      # Create unlinked members
      create_unlinked_members(3)

      {:ok, view, _html} = live(conn, ~p"/users/new")

      # Focus the member search input
      view
      |> element("#member-search-input")
      |> render_focus()

      html = render(view)

      # Dropdown should now be visible
      assert html =~ ~r/role="listbox"/
    end

    test "dropdown shows top 10 unlinked members on focus", %{conn: conn} do
      conn = setup_admin_conn(conn)
      # Create 15 unlinked members
      _members = create_unlinked_members(15)

      {:ok, view, _html} = live(conn, ~p"/users/new")

      # Focus the member search input
      view
      |> element("#member-search-input")
      |> render_focus()

      html = render(view)

      # Count how many member entries are shown in the dropdown
      # Each member creates a div with role="option"
      member_count = html |> String.split(~r/role="option"/) |> length() |> Kernel.-(1)

      # Should show exactly 10 members (limit)
      assert member_count == 10
    end
  end

  describe "email handling" do
    test "links user and member with identical email successfully", %{conn: conn} do
      conn = setup_admin_conn(conn)

      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      {:ok, member} =
        Membership.create_member(
          %{
            first_name: "David",
            last_name: "Miller",
            email: "david@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, ~p"/users/new")

      # Fill user form with same email
      view
      |> form("#user-form", user: %{email: "david@example.com"})
      |> render_change()

      # Focus input
      view
      |> element("#member-search-input")
      |> render_focus()

      # Select member
      view
      |> element("[data-member-id='#{member.id}']")
      |> render_click()

      # Submit form
      view
      |> form("#user-form", user: %{email: "david@example.com"})
      |> render_submit()

      # Should succeed without errors
      assert_redirected(view, ~p"/users")
    end

    test "shows member with same email in dropdown", %{conn: conn} do
      conn = setup_admin_conn(conn)

      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Emma",
            last_name: "Davis",
            email: "emma@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, ~p"/users/new")

      # Fill user form with same email
      view
      |> form("#user-form", user: %{email: "emma@example.com"})
      |> render_change()

      # Focus the member search to trigger loading
      view
      |> element("#member-search-input")
      |> render_focus()

      html = render(view)

      # Should show member with matching email in dropdown
      assert html =~ "Emma Davis"
      assert html =~ "emma@example.com"
    end
  end

  # Helper functions
  defp create_unlinked_members(count) do
    system_actor = Mv.Helpers.SystemActor.get_system_actor()

    for i <- 1..count do
      {:ok, member} =
        Membership.create_member(
          %{
            first_name: "FirstName#{i}",
            last_name: "LastName#{i}",
            email: "member#{i}@example.com"
          },
          actor: system_actor
        )

      member
    end
  end
end
