import React, { useEffect, useCallback, PropsWithChildren } from "react";
import { useForm, FieldValues, DeepPartial } from "react-hook-form";
import { Form } from "react-compose-form";
import { useTranslations } from "next-intl";
import { Search } from "lucide-react";
import { InputControl } from "@/components/form/control/input.control";

type Props<T> = PropsWithChildren<{
    search?: boolean;
    filters: T;
    onChange?: (data: DeepPartial<T>) => void;
}>;

export const DatasetFilters = <T extends FieldValues>(props: Props<T>) => {
    const {
        search,
        filters,
        onChange,
        children
    } = props;

    const t = useTranslations();

    const form = useForm<T>({
        mode: "onChange",
        values: Object.entries(filters).reduce((filters, [key, value]) => {
            if(value === null) {
                return filters;
            }

            return {
                ...filters,
                [key]: value
            };
        }, {} as T)
    });

    const handleChange = useCallback(async (data: DeepPartial<T>) => {
        if(!onChange) {
            return;
        }

        const res = Object.fromEntries(
            Object.entries(data).map(([k, v]) => {
                if(typeof v === "undefined") {
                    return [k, null];
                }

                return [k, v];
            })
        );

        onChange(res as DeepPartial<T>);
    }, [onChange]);

    useEffect(() => {
        const watch = form.watch(handleChange);

        return () => watch.unsubscribe();
    }, [handleChange, form]);

    return (
        <Form<T>
          className="flex flex-row items-center gap-2"
          mode="all"
          formControl={form}>
            {search && (
                <div className="relative">
                    <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />

                    <InputControl
                      className="pl-8"
                      placeholder={t("dashboard.general.fields.search.placeholder")}
                      name="search" />
                </div>
            )}

            {children}
        </Form>
    );
};
