import React, { ReactNode, useEffect, useRef, useState } from 'react';
import "./search-bar.scss";
import ClearButton from "../ClearButton/ClearButton";

type SearchBarProps = {
    onSearch: (searchTerm: string) => void;
    placeholder?: string;
    inputDisabled?: boolean;
    children: ReactNode | ReactNode[];
    value: string;
    hasSearch?: boolean;
    hasExtraSearch?: boolean;
    theme?: 'default' | 'single';
    min?: number;
    type?: 'text' | 'number';
    disableAutoSearch?: boolean;
};

const SearchBar = ({
                       theme = 'default',
                       type = 'text',
                       onSearch,
                       inputDisabled = false,
                       placeholder,
                       children,
                       hasSearch = true,
                       hasExtraSearch = false,
                       value = '',
                       min,
                       disableAutoSearch = false,
                   }: SearchBarProps) => {

    const [searchTerm, setSearchTerm] = useState(value);
    const inputRef = useRef<HTMLDivElement>(null);
    const placeholderRef = useRef<HTMLDivElement>(null);
    const [placeholderAnimation, setPlaceholderAnimation] = useState<boolean | null>(null);

    const childrenArray = React.Children.toArray(children);
    const extraChild = hasExtraSearch ? childrenArray[childrenArray.length - 1] : null;
    const mainChildren = hasExtraSearch ? childrenArray.slice(0, -1) : childrenArray;

    const inputWidth = inputRef.current?.clientWidth;
    const placeholderWidth = placeholderRef.current?.clientWidth;

    const isAllowedToSearch = (): boolean => {
        if (min === undefined) return true;
        if (searchTerm === '') return true;
        if (type === 'text') return searchTerm.length >= min;
        if (type === 'number') {
            const num = Number(searchTerm);
            return !isNaN(num) && num >= min;
        }
        return true;
    };

    // Debounced auto-search (skips when disableAutoSearch = true)
    useEffect(() => {
        if (disableAutoSearch) return;

        const timeout = setTimeout(() => {
            // only call onSearch if the internal value differs from prop value
            if (value !== searchTerm && isAllowedToSearch()) {
                onSearch(searchTerm);
            }
        }, 500);

        return () => clearTimeout(timeout);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [searchTerm, disableAutoSearch]);

    // Keep internal state in sync with prop changes
    useEffect(() => {
        setSearchTerm(value);
    }, [value]);

    useEffect(() => {
        if (inputRef.current && placeholderRef.current) {
            const iw = inputRef.current.clientWidth;
            const pw = placeholderRef.current.clientWidth;
            setPlaceholderAnimation(pw > iw);
        }
    }, [inputWidth, placeholderWidth]);

    return (
        <div className={`search-bar ${theme}`} id="search-bar">
            {mainChildren.map((c, i) => (
                <div className="search-bar-item" key={i}>
                    {c}
                </div>
            ))}

            {hasSearch && (
                <>
                    <div ref={inputRef} className="input-container">
                        <input
                            disabled={inputDisabled}
                            type={type}
                            placeholder={theme === 'default' ? placeholder : ''}
                            value={searchTerm}
                            onChange={(e) => {
                                const newValue = e.target.value;
                                setSearchTerm(newValue);

                                // Only call onSearch immediately if auto search is disabled
                                // or when value passes the min condition
                                if (disableAutoSearch) {
                                    if (isAllowedToSearch()) onSearch(newValue);
                                }
                            }}
                        />
                        {searchTerm === '' && (
                            <div
                                ref={placeholderRef}
                                className={`placeholder-text ${placeholderAnimation ? "animate" : ""}`}
                            >
                                {placeholder}
                            </div>
                        )}
                    </div>

                    <ClearButton theme={theme} term={searchTerm} clear={() => setSearchTerm("")} />
                </>
            )}

            {hasExtraSearch && extraChild && (
                <div className="search-bar-item search-bar-item--extra">
                    {extraChild}
                </div>
            )}
        </div>
    );
};

export default SearchBar;
