defmodule MvWeb.MemberFieldLive.IndexComponentTest do
  @moduledoc """
  Tests for MemberFieldLive.IndexComponent.

  Tests cover:
  - Rendering all member fields from Mv.Constants.member_fields()
  - Displaying show_in_overview status as badge (Yes/No)
  - Displaying required status from settings.member_field_required (email is always required)
  - Current status is displayed based on settings.member_field_visibility and member_field_required
  - Default status is "Yes" (visible) when not configured in settings
  """
  use MvWeb.ConnCase, async: false

  import Phoenix.LiveViewTest

  alias Mv.Membership

  setup %{conn: conn} do
    user = create_test_user(%{email: "admin@example.com"})
    conn = conn_with_oidc_user(conn, user)
    {:ok, conn: conn, user: user}
  end

  describe "rendering" do
    test "renders all member fields from Constants", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Check that all member fields are displayed
      member_fields = Mv.Constants.member_fields()

      for field <- member_fields do
        field_name = String.replace(Atom.to_string(field), "_", " ") |> String.capitalize()
        # Field name should appear in the table (either as label or in some form)
        assert html =~ field_name or html =~ Atom.to_string(field)
      end
    end

    test "displays show_in_overview status as badge", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Should have "Show in overview" column header
      assert html =~ "Show in overview" or html =~ "Show in Overview"

      # Should have badge elements (Yes/No)
      assert html =~ "badge" or html =~ "Yes" or html =~ "No"
    end

    test "displays required status column", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Should have "Required" column; email is always required
      assert html =~ "Required" or html =~ "required"
    end

    test "shows default status as Yes when not configured", %{conn: conn} do
      # Ensure settings have no member_field_visibility configured
      {:ok, settings} = Membership.get_settings()

      {:ok, _updated} =
        Membership.update_settings(settings, %{member_field_visibility: %{}})

      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # All fields should show as visible (Yes) by default
      # Check for "Yes" badge or similar indicator
      assert html =~ "Yes" or html =~ "badge-success"
    end

    test "shows configured visibility status from settings", %{conn: conn} do
      # Configure some fields as hidden
      {:ok, settings} = Membership.get_settings()
      visibility_config = %{"street" => false, "house_number" => false}

      {:ok, _updated} =
        Membership.update_member_field_visibility(settings, visibility_config)

      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Street and house_number should show as hidden (No)
      # Other fields should show as visible (Yes)
      assert html =~ "street" or html =~ "Street"
      assert html =~ "house_number" or html =~ "House number"
    end
  end

  describe "required fields" do
    setup do
      {:ok, settings} = Membership.get_settings()
      saved_visibility = settings.member_field_visibility || %{}
      saved_required = settings.member_field_required || %{}

      on_exit(fn ->
        {:ok, s} = Membership.get_settings()

        Membership.update_settings(s, %{
          member_field_visibility: saved_visibility,
          member_field_required: saved_required
        })
      end)

      :ok
    end

    test "marks email as required (always from settings)", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Email is always required
      assert html =~ "email" or html =~ "Email"
      assert html =~ "Required" or html =~ "Optional"
    end

    test "when first_name is set required in settings, table shows Required", %{conn: conn} do
      {:ok, settings} = Membership.get_settings()

      {:ok, _} =
        Membership.update_single_member_field(settings,
          field: "first_name",
          show_in_overview: true,
          required: true
        )

      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # First name row should show Required (and Optional for others)
      assert html =~ "First name" or html =~ "first_name"
      assert html =~ "Required"
    end

    test "optional fields show Optional when not required in settings", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/datafields")

      # Email is required; other fields default to optional
      assert html =~ "Optional"
      assert html =~ "Required"
    end
  end
end
