import { FormServerErrors } from "@/components/form-common/form-server-errors";
import { Standard400Error } from "@/lib/errors";
import { handleFormElementSubmitEvent, handleSubmitErrors } from "@/lib/form";
import { enableActx, useActx } from "@/testutils/use-actx";
import { useForm } from "@tanstack/react-form";
import { getNodeText, render } from "@testing-library/react";
import { expect, suite, test } from "vitest";

enableActx();

suite("FormServerErrors", () => {
  test("<FormServerErrors />", async () => {
    const actx = useActx();

    function TestingFormComponent() {
      const form = useForm({
        async onSubmit({ formApi, value }) {
          await handleSubmitErrors(formApi, () =>
            Promise.reject(
              Standard400Error.of({
                foo: ["invalid"],
                unknown: ["some server error"],
              })
            )
          );
          formApi.reset(value, { keepDefaultValues: false });
        },
      });

      return (
        <form onSubmit={handleFormElementSubmitEvent(form)}>
          <form.Field name="foo">{() => null}</form.Field>
          <button type="submit">submit</button>
          <FormServerErrors formApi={form} title="failed to submit" />
        </form>
      );
    }

    const ui = render(<TestingFormComponent />);
    expect(ui.queryByRole("alert")).toBeNull();

    await actx(() => {
      ui.getByRole("button", { name: "submit" }).click();
    }, 2);

    const alert = ui.queryByRole("alert")!;
    expect(getNodeText(alert.getElementsByTagName("h5").item(0)!)).toEqual(
      "failed to submit"
    );
    expect(getNodeText(alert.getElementsByTagName("div").item(0)!)).toEqual(
      "some server error"
    );
  });
});
