import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import { StringField } from '../string-field/index.js';
import { Form } from './form.js';
import { PasswordField } from '../password-field/index.js';
import { EmailField } from '../email-field/index.js';
describe('Form', () => {
    it('should render children as React nodes', () => {
        render(_jsx(Form, { onSubmit: () => undefined, children: _jsx("div", { "data-testid": "child", children: "Test Child" }) }));
        expect(screen.getByTestId('child')).toBeInTheDocument();
    });
    it('should render children as function with form methods', () => {
        render(_jsx(Form, { onSubmit: () => undefined, children: (methods) => _jsx("div", { "data-testid": "child", children: methods.formState.isSubmitting ? 'Submitting' : 'Not Submitting' }) }));
        expect(screen.getByTestId('child')).toHaveTextContent('Not Submitting');
    });
    it('should call onSubmit with form data', async () => {
        const handleSubmit = vi.fn();
        render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(StringField, { name: "test", defaultValue: "test-value" }), _jsx("button", { type: "submit", children: "Submit" })] }));
        fireEvent.click(screen.getByText('Submit'));
        await waitFor(() => {
            expect(handleSubmit).toHaveBeenCalledWith({
                test: 'test-value',
            });
        });
    });
    it('should reset form after successful submit when resetOnSuccessfulSubmit is true', async () => {
        const user = userEvent.setup();
        const handleSubmit = vi.fn();
        render(_jsxs(Form, { onSubmit: handleSubmit, resetOnSuccessfulSubmit: true, defaultValues: { test: 'hello' }, children: [_jsx(StringField, { name: "test" }), _jsx("button", { type: "submit", children: "Submit" })] }));
        // type something in the input
        const stringField = screen.getByRole('textbox');
        await user.type(stringField, ' world');
        expect(stringField).toHaveValue('hello world');
        const input = screen.getByRole('textbox');
        fireEvent.click(screen.getByText('Submit'));
        await waitFor(() => {
            expect(input).toHaveValue('hello');
        });
    });
    it('should submit only changed values when submitChangesOnly is true', async () => {
        const handleSubmit = vi.fn();
        const user = userEvent.setup();
        const defaultValues = { unchanged: 'default', changed: 'old' };
        render(_jsxs(Form, { onSubmit: handleSubmit, defaultValues: defaultValues, submitChangesOnly: true, children: [_jsx(StringField, { name: "unchanged" }), _jsx(StringField, { name: "changed" }), _jsx("button", { type: "submit", children: "Submit" })] }));
        const changedInput = screen.getByDisplayValue('old');
        await user.clear(changedInput);
        await user.type(changedInput, 'new');
        fireEvent.click(screen.getByText('Submit'));
        await waitFor(() => {
            expect(handleSubmit).toHaveBeenCalledWith({
                changed: 'new',
            });
        });
    });
    it('should submit null for empty values', async () => {
        const handleSubmit = vi.fn();
        render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(StringField, { name: "empty" }), _jsx("button", { type: "submit", children: "Submit" })] }));
        fireEvent.click(screen.getByText('Submit'));
        await waitFor(() => {
            expect(handleSubmit).toHaveBeenCalledWith({
                empty: null,
            });
        });
    });
    it('should apply className to form element', () => {
        render(
        // disable tailwind custom classname rule for this test
        _jsx(Form, { onSubmit: () => undefined, className: "test-class", children: "Test" }));
        expect(screen.getByText('Test')).toHaveClass('test-class');
    });
    describe('PasswordField with matchFieldName', () => {
        it('should not submit field when it has matchFieldName set', async () => {
            const handleSubmit = vi.fn();
            render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(PasswordField, { name: "password", defaultValue: "@A1a" }), _jsx(PasswordField, { name: "confirmPassword", defaultValue: "@A1a", matchFieldName: "password" }), _jsx("button", { type: "submit", children: "Submit" })] }));
            fireEvent.click(screen.getByText('Submit'));
            await waitFor(() => {
                expect(handleSubmit).toHaveBeenCalledWith({
                    password: '@A1a',
                });
            });
        });
        it('should submit fields when matchFieldName is not set', async () => {
            const handleSubmit = vi.fn();
            render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(PasswordField, { name: "password", defaultValue: "@A1a" }), _jsx(PasswordField, { name: "confirmPassword", defaultValue: "@A1a" }), _jsx("button", { type: "submit", children: "Submit" })] }));
            fireEvent.click(screen.getByText('Submit'));
            await waitFor(() => {
                expect(handleSubmit).toHaveBeenCalledWith({
                    password: '@A1a',
                    confirmPassword: '@A1a',
                });
            });
        });
    });
    describe('EmailField with matchFieldName', () => {
        it('should submit field when it has matchFieldName set', async () => {
            const handleSubmit = vi.fn();
            render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(EmailField, { name: "email", defaultValue: "test@example.com" }), _jsx(EmailField, { name: "confirmEmail", defaultValue: "test@example.com", matchFieldName: "email" }), _jsx("button", { type: "submit", children: "Submit" })] }));
            fireEvent.click(screen.getByText('Submit'));
            await waitFor(() => {
                expect(handleSubmit).toHaveBeenCalledWith({
                    email: 'test@example.com',
                });
            });
        });
        it('should submit fields when matchFieldName is not set', async () => {
            const handleSubmit = vi.fn();
            render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(EmailField, { name: "email", defaultValue: "test@example.com" }), _jsx(EmailField, { name: "confirmEmail", defaultValue: "test@example.com" }), _jsx("button", { type: "submit", children: "Submit" })] }));
            fireEvent.click(screen.getByText('Submit'));
            await waitFor(() => {
                expect(handleSubmit).toHaveBeenCalledWith({
                    email: 'test@example.com',
                    confirmEmail: 'test@example.com',
                });
            });
        });
        it('should show validation error when matchFieldName values do not match', async () => {
            const user = userEvent.setup();
            const handleSubmit = vi.fn();
            render(_jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(EmailField, { name: "email", label: "Email", value: "test@example.com" }), _jsx(EmailField, { name: "confirmEmail", label: "Confirm Email", matchFieldName: "email", showErrorOnBlur: true }), _jsx("button", { type: "submit", children: "Submit" })] }));
            const confirmInput = screen.getByLabelText('Confirm Email');
            await user.type(confirmInput, 'different@example.com');
            await user.tab();
            expect(screen.getByText('Email must match the "Email" field')).toBeInTheDocument();
        });
    });
});
//# sourceMappingURL=form.test.js.map