defmodule MvWeb.MemberLive.IndexGroupsAccessibilityTest do
  @moduledoc """
  Tests for accessibility of groups feature in the member overview.

  Tests cover:
  - Badges have aria-label for group membership (no role="status"; reserved for live regions)
  - Filter dropdown has aria-label
  - Sort header has aria-label for screen reader
  - Keyboard navigation works (Tab through filter, sort header)
  """
  # async: false to prevent PostgreSQL deadlocks when creating members and groups
  use MvWeb.ConnCase, async: false
  import Phoenix.LiveViewTest
  require Ash.Query

  alias Mv.Membership.{Group, MemberGroup}

  setup do
    system_actor = Mv.Helpers.SystemActor.get_system_actor()

    # Create test members
    {:ok, member1} =
      Mv.Membership.create_member(
        %{first_name: "Alice", last_name: "Anderson", email: "alice@example.com"},
        actor: system_actor
      )

    # Create test groups
    {:ok, group1} =
      Group
      |> Ash.Changeset.for_create(:create, %{name: "Board Members"})
      |> Ash.create(actor: system_actor)

    # Create member-group associations
    {:ok, _mg1} =
      MemberGroup
      |> Ash.Changeset.for_create(:create, %{member_id: member1.id, group_id: group1.id})
      |> Ash.create(actor: system_actor)

    %{
      member1: member1,
      group1: group1
    }
  end

  @tag :ui
  test "group badges have aria-label for screen readers", %{
    conn: conn,
    member1: member1,
    group1: group1
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, html} = live(conn, "/members")

    # Verify badges have aria-label containing the group name (no role=status on badges)
    assert has_element?(view, "span[aria-label*='#{group1.name}']")
    assert html =~ group1.name

    # Verify member1's row contains the badge
    assert html =~ member1.first_name
  end

  @tag :ui
  test "filter dropdown has group presence section with legend", %{
    conn: conn
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, _html} = live(conn, "/members")

    # Open filter dropdown
    view
    |> element("button[aria-label='Filter members']")
    |> render_click()

    html = render(view)
    # Groups section: legend "Member has groups" and radios (Any / Yes / No)
    assert html =~ ~r/[Gg]roups/
    assert has_element?(view, "[data-testid='member-filter-form']")
  end

  @tag :ui
  test "sort header has aria-label for screen reader", %{
    conn: conn
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, _html} = live(conn, "/members")

    # Verify sort header has aria-label describing the sort state
    assert has_element?(view, "[data-testid='groups'][aria-label]")
  end

  @tag :ui
  test "keyboard navigation works for filter dropdown", %{
    conn: conn,
    member1: member1,
    group1: group1
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, _html} = live(conn, "/members")

    view
    |> element("button[aria-label='Filter members']")
    |> render_click()

    view
    |> element("[data-testid='member-filter-form']")
    |> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})

    html = render(view)
    assert html =~ member1.first_name
  end

  @tag :ui
  test "keyboard navigation works for sort header", %{
    conn: conn
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, _html} = live(conn, "/members")

    assert has_element?(view, "[data-testid='groups']")

    view
    |> element("[data-testid='groups']")
    |> render_click()

    # Verify sort was applied (URL may include other params)
    assert has_element?(view, "[data-testid='groups'][aria-label*='ascending']")
  end

  @tag :ui
  test "screen reader announcements for filter changes", %{
    conn: conn,
    member1: member1,
    group1: group1
  } do
    conn = conn_with_oidc_user(conn)
    {:ok, view, _html} = live(conn, "/members")

    view
    |> element("button[aria-label='Filter members']")
    |> render_click()

    view
    |> element("[data-testid='member-filter-form']")
    |> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})

    html = render(view)
    assert html =~ member1.first_name
  end

  @tag :ui
  test "multiple badges are announced correctly", %{
    conn: conn,
    member1: member1
  } do
    system_actor = Mv.Helpers.SystemActor.get_system_actor()

    # Create multiple groups for member1
    {:ok, group2} =
      Group
      |> Ash.Changeset.for_create(:create, %{name: "Active Members"})
      |> Ash.create(actor: system_actor)

    {:ok, _mg} =
      MemberGroup
      |> Ash.Changeset.for_create(:create, %{member_id: member1.id, group_id: group2.id})
      |> Ash.create(actor: system_actor)

    conn = conn_with_oidc_user(conn)
    {:ok, _view, html} = live(conn, "/members")

    # Verify multiple badges are present
    assert html =~ member1.first_name
    # Both groups should be visible
    # Screen reader should be able to distinguish between multiple badges
    assert html
  end
end
