import React, { useCallback, useRef, useState, useEffect } from "react";
import { HexColorPicker } from "react-colorful";
import style from "./ColorPicker.module.css";
interface useClickOutsideProps {
    ref: React.RefObject<HTMLElement>;
    handler: (e: MouseEvent) => void;
}

const useClickOutside = ({ ref, handler }: useClickOutsideProps) => {
    useEffect(() => {
        let startedInside = false;
        let startedWhenMounted = false;

        const listener = (event: MouseEvent) => {
            // Do nothing if `mousedown` or `touchstart` started inside ref element
            if (startedInside || !startedWhenMounted) return;
            // Do nothing if clicking ref's element or descendent elements
            if (!ref.current || ref.current.contains(event.target as Node)) return;

            handler(event);
        };

        const validateEventStart = (event: MouseEvent | TouchEvent) => {
            startedWhenMounted = !!ref.current;
            startedInside = !!ref.current?.contains(event.target as Node);
        };

        document.addEventListener("mousedown", validateEventStart);
        document.addEventListener("touchstart", validateEventStart);
        document.addEventListener("click", listener);

        return () => {
            document.removeEventListener("mousedown", validateEventStart);
            document.removeEventListener("touchstart", validateEventStart);
            document.removeEventListener("click", listener);
        };
    }, [ref, handler]);
};

export const PopoverPicker = ({
    color,
    onChange,
    placeholder,
}: {
    color: string;
    onChange: (color: string) => void;
    placeholder?: string;
}) => {
    const popover = useRef<HTMLDivElement>(null);
    const [isOpen, toggle] = useState(false);

    const close = useCallback(() => toggle(false), []);
    useClickOutside({ ref: popover, handler: close });

    return (
        <>
            {placeholder && <div className={style.pickerLabel}>{placeholder}</div>}
            <div className={style.picker}>
                <div
                    className={style.swatch}
                    style={{ backgroundColor: color }}
                    onClick={() => toggle(true)}
                />

                {isOpen && (
                    <div className={style.popover} ref={popover}>
                        <HexColorPicker color={color} onChange={onChange} />
                    </div>
                )}
            </div>
        </>
    );
};
