defmodule MvWeb.UserLive.ShowTest do
  @moduledoc """
  Tests for the user show page.

  Tests cover:
  - Displaying user information
  - Authentication status display
  - Linked member display
  - Navigation
  - Error handling
  """
  use MvWeb.ConnCase, async: true
  import Phoenix.LiveViewTest
  require Ash.Query
  use Gettext, backend: MvWeb.Gettext

  setup do
    # Create test user
    user = create_test_user(%{email: "test@example.com", oidc_id: "test123"})
    %{user: user}
  end

  describe "mount and display" do
    @tag :ui
    test "mounts successfully and displays user information", %{conn: conn, user: user} do
      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      # Basic display
      assert html =~ to_string(user.email)
      assert html =~ gettext("Email")
    end

    test "displays password authentication status when enabled", %{conn: conn} do
      user = create_test_user(%{email: "password-user@example.com", password: "test123"})
      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      assert html =~ gettext("Password Authentication")
      assert html =~ gettext("Enabled")
    end

    test "displays password authentication status when not enabled", %{conn: conn} do
      # User without password (only OIDC) - create user with OIDC only
      user =
        create_test_user(%{
          email: "oidc-only#{System.unique_integer([:positive])}@example.com",
          oidc_id: "oidc#{System.unique_integer([:positive])}",
          hashed_password: nil
        })

      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      assert html =~ gettext("Password Authentication")
      assert html =~ gettext("Not enabled")
    end

    @tag :slow
    test "displays linked member when present", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

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

      # Create user and link to member
      user = create_test_user(%{email: "user@example.com"})

      {:ok, _updated_user} =
        user
        |> Ash.Changeset.for_update(:update, %{})
        |> Ash.Changeset.manage_relationship(:member, member, type: :append_and_remove)
        |> Ash.update(actor: system_actor)

      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      assert html =~ gettext("Linked Member")
      assert html =~ "Alice Smith"
      assert html =~ ~r/href="[^"]*\/members\/#{member.id}"/
    end

    test "displays 'No member linked' when no member is linked", %{conn: conn, user: user} do
      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      assert html =~ gettext("Linked Member")
      assert html =~ gettext("No member linked")
    end
  end

  describe "navigation" do
    @tag :ui
    test "navigation buttons work correctly", %{conn: conn, user: user} do
      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, ~p"/users/#{user.id}")

      # Back button navigates to user list
      assert {:error, {:live_redirect, %{to: to}}} =
               view
               |> element(
                 "a[aria-label='#{gettext("Back to users list")}'], button[aria-label='#{gettext("Back to users list")}']"
               )
               |> render_click()

      assert to == "/users"

      # Edit button navigates to edit form
      {:ok, view, _html} = live(conn, ~p"/users/#{user.id}")

      assert {:error, {:live_redirect, %{to: to}}} =
               view
               |> element(
                 "a[href='/users/#{user.id}/edit?return_to=show'], button[href='/users/#{user.id}/edit?return_to=show']"
               )
               |> render_click()

      assert to == "/users/#{user.id}/edit?return_to=show"
    end
  end

  describe "page title" do
    @tag :ui
    test "sets correct page title", %{conn: conn, user: user} do
      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/users/#{user.id}")

      # Check that page title is set (might be in title tag or header)
      assert html =~ gettext("Show User") || html =~ to_string(user.email)
    end
  end

  describe "error handling" do
    test "raises exception for invalid user ID", %{conn: conn} do
      invalid_id = Ecto.UUID.generate()
      conn = conn_with_oidc_user(conn)

      # The mount function uses Ash.get! which will raise an exception
      # This is expected behavior - the LiveView doesn't handle this case
      assert_raise Ash.Error.Invalid, fn ->
        live(conn, ~p"/users/#{invalid_id}")
      end
    end
  end

  describe "system actor user" do
    @tag :slow
    test "redirects to user list when viewing system actor user", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()
      conn = conn_with_oidc_user(conn)

      assert {:error, {:live_redirect, %{to: "/users"}}} =
               live(conn, ~p"/users/#{system_actor.id}")
    end
  end
end
