defmodule MvWeb.UserLive.Index do
  @moduledoc """
  LiveView for displaying and managing the user list.

  ## Features
  - List all users with email and linked member
  - Sort users by email (default)
  - Navigate to user details (row click) and edit from details header
  - Delete only via Danger zone on user show/edit

  ## Relationships
  Displays linked member information when a user is connected to a member account.

  ## Security
  User deletion requires admin permissions (enforced by Ash policies).
  """
  use MvWeb, :live_view
  import MvWeb.TableComponents

  import MvWeb.LiveHelpers, only: [current_actor: 1]

  require Ash.Query

  @impl true
  def mount(_params, _session, socket) do
    actor = current_actor(socket)

    users =
      Mv.Accounts.User
      |> Ash.Query.filter(email != ^Mv.Helpers.SystemActor.system_user_email())
      |> Ash.read!(domain: Mv.Accounts, load: [:member, :role], actor: actor)

    sorted = Enum.sort_by(users, & &1.email)

    {:ok,
     socket
     |> assign(:page_title, gettext("Listing Users"))
     |> assign(:sort_field, :email)
     |> assign(:sort_order, :asc)
     |> assign(:users, sorted)}
  end

  # Sorts the list of users according to a field, when you click on the column header
  @impl true
  def handle_event("sort", %{"field" => field_str}, socket) do
    users = socket.assigns.users
    field = String.to_existing_atom(field_str)

    new_order =
      if socket.assigns.sort_field == field do
        toggle_order(socket.assigns.sort_order)
      else
        :asc
      end

    sorted_users =
      users
      |> Enum.sort_by(&Map.get(&1, field), sort_fun(new_order))

    {:noreply,
     socket
     |> assign(:sort_field, field)
     |> assign(:sort_order, new_order)
     |> assign(:users, sorted_users)}
  end

  defp toggle_order(:asc), do: :desc
  defp toggle_order(:desc), do: :asc
  defp sort_fun(:asc), do: &<=/2
  defp sort_fun(:desc), do: &>=/2
end
