import { render, screen, fireEvent } from "@solidjs/testing-library";
import { describe, expect, it, vi } from "vitest";
import { z } from "zod/v4";
import { Form } from "../../../src/components/form/index";

const schema = z.object({
  username: z.string().min(3, "Username must be at least 3 characters"),
});

describe("Form — validation", () => {
  it("shows Zod errors on submit", async () => {
    render(() => (
      <Form schema={schema}>
        <Form.Field name="username">
          <Form.Control>{(p) => <input {...p} />}</Form.Control>
          <Form.ErrorMessage />
        </Form.Field>
        <Form.Submit>Submit</Form.Submit>
      </Form>
    ));
    fireEvent.click(screen.getByRole("button", { name: "Submit" }));
    await Promise.resolve();
    expect(screen.getByRole("alert").textContent).toBeTruthy();
  });

  it("calls onValidationError with field errors", async () => {
    const onValidationError = vi.fn();
    render(() => (
      <Form schema={schema} onValidationError={onValidationError}>
        <Form.Field name="username">
          <Form.Control>{(p) => <input {...p} />}</Form.Control>
        </Form.Field>
        <Form.Submit>Submit</Form.Submit>
      </Form>
    ));
    fireEvent.click(screen.getByRole("button", { name: "Submit" }));
    await Promise.resolve();
    expect(onValidationError).toHaveBeenCalled();
    const errArg = onValidationError.mock.calls[0][0] as Record<string, string[]>;
    expect(Array.isArray(errArg["username"])).toBe(true);
  });

  it("error message render prop receives errors array", async () => {
    render(() => (
      <Form schema={schema}>
        <Form.Field name="username">
          <Form.Control>{(p) => <input {...p} />}</Form.Control>
          <Form.ErrorMessage>
            {(errors: string[]) => <span data-testid="errs">{errors[0]}</span>}
          </Form.ErrorMessage>
        </Form.Field>
        <Form.Submit>Submit</Form.Submit>
      </Form>
    ));
    fireEvent.click(screen.getByRole("button", { name: "Submit" }));
    await Promise.resolve();
    expect(screen.getByTestId("errs").textContent).toBeTruthy();
  });

});
