const defaultOptions = {
    containerSelector: "#container",
    sliderSelector: ".slider-wrapper"
}

const useSlider = (options, makeupEngine, callback) => {
    let resolvedOptions = Object.assign({}, defaultOptions, options ?? {});

    const handle = document.querySelector(resolvedOptions.sliderSelector);
    const container = document.querySelector(resolvedOptions.containerSelector);

    let dragging = false;

    // event options
    const opts = {
        capture: false,
        passive: false
    }

    const handleStart = () => dragging = true;
    handle.addEventListener('mousedown', handleStart, opts);
    handle.addEventListener('touchstart', handleStart, opts);

    const handleEnd = () => dragging = false;
    document.addEventListener('mouseup', handleEnd, opts);
    document.addEventListener('touchend', handleEnd, opts);
    document.addEventListener('touchcancel', handleEnd, opts);

    const sliderContainerWidth = 8;

    let handlePosition = 0; // do not update manually, use setHandlePosition( ... )
    const setHandlePosition = (x) => {
        handlePosition = x;
        handle.style = "left: " + (handlePosition - sliderContainerWidth / 2) + "px";

        let sliderPosition = (handlePosition / (container.clientWidth || 1));

        const makeupView = makeupEngine?.GetView();
        const fullAspectRatio = makeupView ? makeupView.width / makeupView.height : 1;

        const fullWidth = container.clientHeight * fullAspectRatio;
        const leftCliped = (fullWidth - container.clientWidth) / 2;
        if (leftCliped > 0) {
            sliderPosition = (handlePosition + leftCliped) / (fullWidth || 1);
        }

        callback(sliderPosition);
    }

    let startingHandlePosition = container.clientWidth / 2
    setHandlePosition(startingHandlePosition);

    const handleMove = (e) => {
        if (dragging === true) {
            const sliderContainerOffset = sliderContainerWidth / 2;
            let x = e.clientX - container.offsetLeft + sliderContainerOffset;
            if (e.changedTouches && e.changedTouches[0]) {
                x = e.changedTouches[0].clientX - container.offsetLeft + sliderContainerOffset;
            }

            x = Math.min(Math.max(0, x), container.clientWidth);

            setHandlePosition(x);
        }
    }
    document.addEventListener('mousemove', handleMove, opts);
    document.addEventListener('touchmove', handleMove, opts);

    const resizeHandler = () => {
        const x = Math.min(Math.max(0, handlePosition), container.clientWidth);
        setHandlePosition(x);
    };
    window.addEventListener('resize', resizeHandler)

    const tearDown = () => {
        handle.removeEventListener('mousedown', handleStart);
        handle.removeEventListener('touchstart', handleStart);
        document.removeEventListener('mouseup', handleEnd);
        document.removeEventListener('touchend', handleEnd);
        document.removeEventListener('touchcancel', handleEnd);
        document.removeEventListener('mousemove', handleMove);
        document.removeEventListener('touchmove', handleMove);
        window.removeEventListener('resize', resizeHandler);
    }

    return tearDown;
}

export default useSlider;
