import { describe, it, expect, vi } from "vitest";
import { renderHook } from "@testing-library/react";
import fc from "fast-check";
import React from "react";
import * as v from "valibot";
import { FormContext } from "../../component/form/form";
import { useInputValidation } from "./index";
describe("hook:useInputValidation", () => {
    const createWrapper = (contextValue = { schema: undefined, isSubmitted: false }) => ({ children }) => (<FormContext.Provider value={contextValue}>
                {children}
            </FormContext.Provider>);
    it("validates correct input", () => {
        let schema = v.string();
        let { result } = renderHook(() => useInputValidation({
            validate: schema,
        }), { wrapper: createWrapper() });
        let element = document.createElement("input");
        element.value = "test";
        let issues = result.current.validate(element);
        expect(issues).toBe(null);
    });
    it("returns issues for invalid input", () => {
        let schema = v.pipe(v.string(), v.email());
        let { result } = renderHook(() => useInputValidation({
            validate: schema,
        }), { wrapper: createWrapper() });
        let element = document.createElement("input");
        element.value = "not-an-email";
        let issues = result.current.validate(element);
        expect(issues).toBeTruthy();
        expect(issues?.length).toBe(1);
    });
    it("calls onValidationError when validation fails", () => {
        let schema = v.pipe(v.string(), v.minLength(5));
        let onValidationError = vi.fn();
        let { result } = renderHook(() => useInputValidation({
            validate: schema,
            onValidationError,
        }), { wrapper: createWrapper() });
        let element = document.createElement("input");
        element.value = "test"; // length 4, should fail
        let issues = result.current.validate(element);
        if (!issues) {
            console.error("Validation unexpectedly passed for value:", element.value);
        }
        expect(issues).toBeTruthy();
        expect(onValidationError).toHaveBeenCalledTimes(1);
        expect(onValidationError).toHaveBeenCalledWith(issues);
    });
    it("handles random string inputs without crashing (fuzzing)", () => {
        fc.assert(fc.property(fc.string(), (input) => {
            let schema = v.string();
            let { result } = renderHook(() => useInputValidation({
                validate: schema,
            }), { wrapper: createWrapper() });
            let element = document.createElement("input");
            element.value = input;
            expect(() => result.current.validate(element)).not.toThrow();
        }));
    });
    it("handles onChange event", () => {
        let onChange = vi.fn();
        let { result } = renderHook(() => useInputValidation({ onChange }), { wrapper: createWrapper() });
        let element = document.createElement("input");
        let event = {
            target: element,
            isDefaultPrevented: () => false,
            persist: () => { },
        };
        result.current.onChange(event);
        expect(onChange).toHaveBeenCalledTimes(1);
    });
    it("handles onBlur event", () => {
        let onBlur = vi.fn();
        let { result } = renderHook(() => useInputValidation({ onBlur }), { wrapper: createWrapper() });
        let element = document.createElement("input");
        let event = {
            target: element,
            isDefaultPrevented: () => false,
            persist: () => { },
        };
        result.current.onBlur(event);
        expect(onBlur).toHaveBeenCalledTimes(1);
    });
});
