import { twMerge } from "tailwind-merge";
import Input, { InputProps } from "../form/Input";
import Button from "../layout/Button";
import Row from "../layout/Row";
import { Search as SearchIcon } from "lucide-react";
import React, { DetailedHTMLProps } from "react";

let timeout: any;

export type SearchProps<KeyType extends string> = DetailedHTMLProps<
    React.HTMLAttributes<HTMLDivElement>,
    HTMLDivElement
> & {
    dispatch?: (value?: string) => void;
    changeHandler?: (value?: string) => void;
    delay?: number;
    inputProps?: InputProps<KeyType>;
    buttonProps?: DetailedHTMLProps<
        React.ButtonHTMLAttributes<HTMLButtonElement>,
        HTMLButtonElement
    >;
    loading?: boolean;
    placeholder?: string;
};

/**
 * # Search Component
 * @className_wrapper twui-search-wrapper
 * @className_circle twui-search-input
 * @className_circle twui-search-button
 */
export default function Search<KeyType extends string>({
    dispatch,
    changeHandler,
    delay = 500,
    inputProps,
    buttonProps,
    loading,
    placeholder,
    ...props
}: SearchProps<KeyType>) {
    const [input, setInput] = React.useState(
        props.defaultValue?.toString() || ""
    );

    React.useEffect(() => {
        clearTimeout(timeout);

        timeout = setTimeout(() => {
            dispatch?.(input);
            changeHandler?.(input);
        }, delay);
    }, [input]);

    const inputRef = React.useRef<HTMLInputElement>(null);

    React.useEffect(() => {
        if (props.autoFocus) {
            inputRef.current?.focus();
        }
    }, []);

    return (
        <Row
            {...props}
            className={twMerge(
                "relative xl:flex-nowrap items-stretch gap-0",
                "twui-search-wrapper",
                props?.className
            )}
        >
            <Input
                type="search"
                placeholder={placeholder || "Search"}
                {...inputProps}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                className={twMerge(
                    "rounded-r-none",
                    "twui-search-input",
                    inputProps?.className
                )}
                wrapperProps={{
                    className: "rounded-r-none",
                }}
                componentRef={inputRef}
            />
            <Button
                loadingProps={{ size: "small" }}
                {...buttonProps}
                variant="outlined"
                color="gray"
                className={twMerge(
                    "rounded-l-none ml-[1px]",
                    "twui-search-button",
                    buttonProps?.className
                )}
                onClick={() => {
                    dispatch?.(input);
                    changeHandler?.(input);
                }}
                title="Search Button"
                loading={loading}
            >
                <SearchIcon
                    className="text-slate-800 dark:text-white"
                    size={20}
                />
            </Button>
        </Row>
    );
}
