import _ from "lodash";
import { DetailedHTMLProps, FormHTMLAttributes, RefObject } from "react";
import { twMerge } from "tailwind-merge";

type Props<T extends { [key: string]: any } = { [key: string]: any }> =
    DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement> & {
        submitHandler?: (e: React.FormEvent<HTMLFormElement>, data: T) => void;
        changeHandler?: (e: React.FormEvent<HTMLFormElement>, data: T) => void;
        formRef?: RefObject<HTMLFormElement>;
    };

/**
 * # Form Element
 * @className twui-form
 */
export default function Form<
    T extends { [key: string]: any } = { [key: string]: any },
>({ formRef, ...props }: Props<T>) {
    const finalProps = _.omit(props, ["submitHandler", "changeHandler"]);

    return (
        <form
            {...finalProps}
            className={twMerge(
                "flex flex-col items-stretch gap-2 w-full bg-transparent",
                "twui-form",
                props.className,
            )}
            onSubmit={(e) => {
                e.preventDefault();
                const formEl = e.target as HTMLFormElement;
                const formData = new FormData(formEl);
                const data = Object.fromEntries(formData.entries()) as T;
                props.submitHandler?.(e, data);
                props.onSubmit?.(e);
            }}
            onChange={(e) => {
                e.preventDefault();
                const taregtEl = e.target as HTMLElement;
                const formEl = taregtEl.closest("form") as HTMLFormElement;
                const formData = new FormData(formEl);
                const data = Object.fromEntries(formData.entries()) as T;
                props.changeHandler?.(e, data);
                props.onChange?.(e);
            }}
            ref={formRef}
        >
            {props.children}
        </form>
    );
}
