import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react';

const Dropdown = (props: any, forwardedRef: any) => {
    const [visibility, setVisibility] = useState(false);

    const mainAxis = Array.isArray(props.offset) ? Number(props.offset[1]) || 0 : Number(props.offset) || 0;
    const crossAxis = Array.isArray(props.offset) ? Number(props.offset[0]) || 0 : 0;

    const { refs, floatingStyles } = useFloating({
        open: visibility,
        placement: props.placement || 'bottom-end',
        middleware: [offset({ mainAxis, crossAxis }), flip(), shift({ padding: 8 })],
        whileElementsMounted: autoUpdate,
    });

    useEffect(() => {
        const handleDocumentClick = (event: MouseEvent) => {
            const reference = refs.reference.current;
            const floating = refs.floating.current;
            const target = event.target;
            if (!(target instanceof Node)) return;
            if (reference instanceof Node && reference.contains(target)) return;
            if (floating instanceof Node && floating.contains(target)) return;
            setVisibility(false);
        };

        document.addEventListener('mousedown', handleDocumentClick);
        return () => {
            document.removeEventListener('mousedown', handleDocumentClick);
        };
    }, [refs]);

    useImperativeHandle(forwardedRef, () => ({
        close() {
            setVisibility(false);
        },
    }));

    return (
        <>
            <button ref={refs.setReference} type="button" className={props.btnClassName} onClick={() => setVisibility(!visibility)}>
                {props.button}
            </button>

            {visibility && (
                <div ref={refs.setFloating} style={floatingStyles} className="z-50" onClick={() => setVisibility(!visibility)}>
                    {props.children}
                </div>
            )}
        </>
    );
};

export default forwardRef(Dropdown);
