defmodule MvWeb.MemberLive.FormErrorHandlingTest do
  @moduledoc """
  Tests for error handling in the member form, specifically flash message display.
  """
  use MvWeb.ConnCase, async: false
  use Gettext, backend: MvWeb.Gettext

  import Phoenix.LiveViewTest

  require Ash.Query

  describe "danger zone on edit" do
    @tag :ui
    test "edit form shows Danger zone and delete button when user can destroy member", %{
      conn: conn
    } do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      {:ok, member} =
        Mv.Membership.create_member(
          %{first_name: "Delete", last_name: "FromEdit", email: "delete.from.edit@example.com"},
          actor: system_actor
        )

      conn = conn_with_oidc_user(conn)
      {:ok, view, html} = live(conn, ~p"/members/#{member}/edit")

      assert html =~ gettext("Danger zone")
      assert has_element?(view, "[data-testid='member-delete']")
    end

    test "delete event from edit form removes member and redirects to /members", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      {:ok, member} =
        Mv.Membership.create_member(
          %{
            first_name: "ToDelete",
            last_name: "FromForm",
            email: "todelete.from.form.#{System.unique_integer([:positive])}@example.com"
          },
          actor: system_actor
        )

      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, ~p"/members/#{member}/edit")

      view
      |> render_click("delete", %{"id" => member.id})

      assert_redirect(view, ~p"/members")

      refute Mv.Membership.Member
             |> Ash.Query.filter(id == ^member.id)
             |> Ash.exists?()
    end
  end

  describe "tab visibility" do
    @tag :ui
    test "Payments tab is not visible on new member form", %{conn: conn} do
      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, "/members/new")

      refute html =~ gettext("Payments")
    end

    @tag :ui
    test "Payments tab is not visible on edit member form", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      {:ok, member} =
        Mv.Membership.create_member(
          %{first_name: "Edit", last_name: "Member", email: "edit@example.com"},
          actor: system_actor
        )

      conn = conn_with_oidc_user(conn)
      {:ok, _view, html} = live(conn, ~p"/members/#{member}/edit")

      refute html =~ gettext("Payments")
    end
  end

  describe "error handling - flash messages" do
    setup do
      {:ok, settings} = Mv.Membership.get_settings()
      saved_visibility = settings.member_field_visibility || %{}
      saved_required = settings.member_field_required || %{}

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

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

      :ok
    end

    @describetag :ui
    test "shows flash message when member creation fails with validation error", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      # Create a member with the same email to trigger uniqueness error
      {:ok, _existing_member} =
        Mv.Membership.create_member(
          %{
            first_name: "Existing",
            last_name: "Member",
            email: "duplicate@example.com"
          },
          actor: system_actor
        )

      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, "/members/new")

      # Try to create member with duplicate email
      form_data = %{
        "member[first_name]" => "New",
        "member[last_name]" => "Member",
        "member[email]" => "duplicate@example.com"
      }

      html =
        view
        |> form("#member-form", form_data)
        |> render_submit()

      # Should show flash error message
      assert has_element?(view, "#flash-group")

      assert html =~ "error" or html =~ "Error" or html =~ "Fehler" or
               html =~ "failed" or html =~ "fehlgeschlagen" or
               html =~ "Validation failed" or html =~ "Validierung fehlgeschlagen"
    end

    test "shows flash message when member creation fails with missing required fields", %{
      conn: conn
    } do
      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, "/members/new")

      # Submit form with missing required fields (e.g., email)
      form_data = %{
        "member[first_name]" => "Test",
        "member[last_name]" => "User"
        # email is missing
      }

      html =
        view
        |> form("#member-form", form_data)
        |> render_submit()

      # Should show flash error message
      assert has_element?(view, "#flash-group")

      assert html =~ "error" or html =~ "Error" or html =~ "Fehler" or
               html =~ "failed" or html =~ "fehlgeschlagen" or
               html =~ "Validation failed" or html =~ "Validierung fehlgeschlagen" or
               html =~ "Please correct" or html =~ "Bitte korrigieren"
    end

    @tag :ui
    test "shows validation error when settings-required field is missing", %{conn: conn} do
      {:ok, settings} = Mv.Membership.get_settings()

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

      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, "/members/new")

      # Submit without first_name (required in settings)
      form_data = %{
        "member[last_name]" => "User",
        "member[email]" => "newuser#{System.unique_integer([:positive])}@example.com"
      }

      html =
        view
        |> form("#member-form", form_data)
        |> render_submit()

      assert html =~ "error" or html =~ "Error" or html =~ "Fehler" or
               html =~ "first_name" or html =~ "First name" or html =~ "can't be blank" or
               html =~ "darf nicht leer sein"
    end

    test "shows flash message when member update fails", %{conn: conn} do
      system_actor = Mv.Helpers.SystemActor.get_system_actor()

      # Create a member to edit
      {:ok, member} =
        Mv.Membership.create_member(
          %{
            first_name: "Original",
            last_name: "Member",
            email: "original@example.com"
          },
          actor: system_actor
        )

      # Create another member with different email
      {:ok, _other_member} =
        Mv.Membership.create_member(
          %{first_name: "Other", last_name: "Member", email: "other@example.com"},
          actor: system_actor
        )

      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, "/members/#{member.id}/edit")

      # Try to update with duplicate email
      form_data = %{
        "member[first_name]" => "Updated",
        "member[last_name]" => "Member",
        "member[email]" => "other@example.com"
      }

      html =
        view
        |> form("#member-form", form_data)
        |> render_submit()

      # Should show flash error message
      assert has_element?(view, "#flash-group")

      assert html =~ "error" or html =~ "Error" or html =~ "Fehler" or
               html =~ "failed" or html =~ "fehlgeschlagen" or
               html =~ "Validation failed" or html =~ "Validierung fehlgeschlagen"
    end

    test "form still displays field-level validation errors when flash message is shown", %{
      conn: conn
    } do
      conn = conn_with_oidc_user(conn)
      {:ok, view, _html} = live(conn, "/members/new")

      # Submit form with invalid email format
      form_data = %{
        "member[first_name]" => "Test",
        "member[last_name]" => "User",
        "member[email]" => "invalid-email-format"
      }

      html =
        view
        |> form("#member-form", form_data)
        |> render_submit()

      # Should show both flash message and field-level error
      assert has_element?(view, "#flash-group")
      # Field-level errors should also be visible in the form
      assert html =~ "email" or html =~ "Email"
    end
  end
end
