defmodule MvWeb.GroupLive.ShowMemberSearchTest do
  @moduledoc """
  UI tests for member search functionality in inline Add Member combobox.
  Tests search behavior and filtering of members already in group.
  """

  use MvWeb.ConnCase, async: false
  import Phoenix.LiveViewTest
  use Gettext, backend: MvWeb.Gettext

  alias Mv.Membership
  alias Mv.Fixtures

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

  describe "search functionality" do
    test "search finds member by exact name", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Jonathan",
            last_name: "Smith",
            email: "jonathan.smith@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "Jonathan"})

      assert has_element?(view, "#member-dropdown", "Jonathan")
      assert has_element?(view, "#member-dropdown", "Smith")
    end

    test "search finds member by partial name (fuzzy)", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Jonathan",
            last_name: "Smith",
            email: "jonathan.smith@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "Jon"})

      assert has_element?(view, "#member-dropdown", "Jonathan")
      assert has_element?(view, "#member-dropdown", "Smith")
    end

    test "search finds member by email", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Alice",
            last_name: "Johnson",
            email: "alice.johnson@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "alice.johnson"})

      assert has_element?(view, "#member-dropdown", "Alice")
      assert has_element?(view, "#member-dropdown", "Johnson")
      assert has_element?(view, "#member-dropdown", "alice.johnson@example.com")
    end

    test "dropdown shows member name and email", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Bob",
            last_name: "Williams",
            email: "bob@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      # Open inline input
      view
      |> element("button", "Add Member")
      |> render_click()

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

      # phx-change is on the form, so we need to trigger it via the form
      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "Bob"})

      assert has_element?(view, "#member-dropdown", "Bob")
      assert has_element?(view, "#member-dropdown", "Williams")
      assert has_element?(view, "#member-dropdown", "bob@example.com")
    end

    test "ComboBox hook works (focus opens dropdown)", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      {:ok, _member} =
        Membership.create_member(
          %{
            first_name: "Charlie",
            last_name: "Brown",
            email: "charlie@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("[data-testid=group-show-member-search-input]")
      |> render_focus()

      assert has_element?(view, "#member-dropdown[role=listbox]")
    end
  end

  describe "filtering members already in group" do
    test "members already in group are NOT shown in search results", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      # Create member and add to group
      {:ok, member_in_group} =
        Membership.create_member(
          %{
            first_name: "David",
            last_name: "Miller",
            email: "david@example.com"
          },
          actor: system_actor
        )

      Membership.create_member_group(%{member_id: member_in_group.id, group_id: group.id},
        actor: system_actor
      )

      # Create another member NOT in group
      {:ok, _member_not_in_group} =
        Membership.create_member(
          %{
            first_name: "David",
            last_name: "Anderson",
            email: "david.anderson@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "David"})

      assert has_element?(view, "#member-dropdown", "Anderson")
      refute has_element?(view, "#member-dropdown", "Miller")
    end

    test "search filters correctly when group has many members", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      # Add multiple members to group
      Enum.each(1..5, fn i ->
        {:ok, m} =
          Membership.create_member(
            %{
              first_name: "Member#{i}",
              last_name: "InGroup",
              email: "member#{i}@example.com"
            },
            actor: system_actor
          )

        Membership.create_member_group(%{member_id: m.id, group_id: group.id},
          actor: system_actor
        )
      end)

      # Create member NOT in group
      {:ok, _member_not_in_group} =
        Membership.create_member(
          %{
            first_name: "Available",
            last_name: "Member",
            email: "available@example.com"
          },
          actor: system_actor
        )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "Available"})

      assert has_element?(view, "#member-dropdown", "Available")
      assert has_element?(view, "#member-dropdown", "Member")
      refute has_element?(view, "#member-dropdown", "Member1")
      refute has_element?(view, "#member-dropdown", "Member2")
    end

    test "search shows no results when all available members are already in group", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = setup_admin_conn(conn)
      group = Fixtures.group_fixture()

      # Create and add all members to group
      {:ok, member} =
        Membership.create_member(
          %{
            first_name: "Only",
            last_name: "Member",
            email: "only@example.com"
          },
          actor: system_actor
        )

      Membership.create_member_group(%{member_id: member.id, group_id: group.id},
        actor: system_actor
      )

      {:ok, view, _html} = live(conn, "/groups/#{group.slug}")

      view
      |> element("button[phx-click='show_add_member_input']")
      |> render_click()

      view
      |> element("form[phx-change='search_members']")
      |> render_change(%{"member_search" => "Only"})

      refute has_element?(view, "#member-dropdown")
    end
  end
end
