import { __read } from "tslib";
import { useEffect, useMemo } from "react";
import { useTheme } from "styled-components";
import { LIGHT_THEME } from "../../Pallette/themes";
import useDebounce from "../../hooks/useDebounce";
import { getTheme } from "../../utils/theme/getTheme";
import { useStateProps } from "../../hooks/useStateProps";
import { defaultThemeSlider } from "../themes";
var getParsed = function (currentFrom, currentTo, min) {
    var from = currentFrom ? parseInt(currentFrom.value, 10) : min;
    var to = parseInt(currentTo.value, 10);
    return [from, to];
};
var getValidValue = function (_a) {
    var value = _a.value, max = _a.max, min = _a.min;
    if (value > max) {
        return max;
    }
    if (value < min) {
        return min;
    }
    return value;
};
var getCorrectPositionHint = function (position, direction) {
    if (direction === "vertical") {
        if (position > 81 && position <= 100) {
            return position - 4;
        }
        else if (position >= 40) {
            return position - 3;
        }
        return position;
    }
    return position;
};
var getMarginVerticalHint = function (value) {
    if (value < 10) {
        return 10;
    }
    else if (value < 20) {
        return 7;
    }
    else if (value < 100) {
        return 4;
    }
    return 0;
};
var getMarginHorizontalHint = function (width) {
    if (width <= 21) {
        return -5;
    }
    else if (width <= 23) {
        return -7;
    }
    else if (width <= 27) {
        return -12;
    }
    else if (width <= 30) {
        return -17;
    }
    return -22;
};
export function useSlider(_a) {
    var min = _a.min, max = _a.max, value = _a.value, defaultValue = _a.defaultValue, isRange = _a.isRange, inputsRef = _a.inputsRef, hintsRef = _a.hintsRef, onChange = _a.onChange, status = _a.status, isDisabled = _a.isDisabled, direction = _a.direction, step = _a.step;
    var theme = getTheme({
        theme: useTheme() || LIGHT_THEME,
        componentName: "slider",
        defaultTheme: defaultThemeSlider
    });
    var _b = __read(useStateProps(value), 2), currentValue = _b[0], setCurrentValue = _b[1];
    var directionOffset = useMemo(function () {
        if (direction === "vertical") {
            return "bottom";
        }
        return "left";
    }, [direction]);
    var _c = __read(useMemo(function () {
        var _rangeDistance = max - min;
        var _fromPosition = 0;
        var _toPosition = 0;
        if (isRange) {
            _fromPosition = currentValue[0] - min;
            _toPosition = currentValue[1] - min;
        }
        else {
            _toPosition = currentValue - min;
        }
        return [_fromPosition, _toPosition, _rangeDistance];
    }, [max, currentValue, isRange, min]), 3), fromPosition = _c[0], toPosition = _c[1], rangeDistance = _c[2];
    useEffect(function () {
        var offsetFrom = (fromPosition / rangeDistance) * 100;
        var offsetTo = (toPosition / rangeDistance) * 100;
        if (hintsRef[0].current) {
            hintsRef[0].current.style[directionOffset] = getCorrectPositionHint(offsetFrom, direction) + "%";
        }
        if (hintsRef[1].current) {
            hintsRef[1].current.style[directionOffset] = getCorrectPositionHint(offsetTo, direction) + "%";
        }
        if (direction === "vertical") {
            if (isRange) {
                if (hintsRef[0].current) {
                    hintsRef[0].current.style.marginLeft = getMarginVerticalHint(currentValue[0]) + "px";
                }
                if (hintsRef[1].current) {
                    hintsRef[1].current.style.marginLeft = getMarginVerticalHint(currentValue[1]) + "px";
                }
            }
            else if (hintsRef[1].current) {
                hintsRef[1].current.style.marginLeft = getMarginVerticalHint(currentValue) + "px";
            }
        }
        else if (isRange) {
            if (hintsRef[0].current) {
                hintsRef[0].current.style.marginLeft = getMarginHorizontalHint(hintsRef[0].current.clientWidth) + "px";
            }
            if (hintsRef[1].current) {
                hintsRef[1].current.style.marginLeft = getMarginHorizontalHint(hintsRef[1].current.clientWidth) + "px";
            }
        }
        else if (hintsRef[1].current) {
            hintsRef[1].current.style.marginLeft = getMarginHorizontalHint(hintsRef[1].current.clientWidth) + "px";
        }
        fillSlider();
    }, [fromPosition, toPosition, direction]);
    useEffect(function () {
        if (direction === "horizontal") {
            if (hintsRef[0].current) {
                hintsRef[0].current.style.removeProperty("bottom");
            }
            if (hintsRef[1].current) {
                hintsRef[1].current.style.removeProperty("bottom");
            }
        }
        else if (direction === "vertical") {
            if (hintsRef[0].current) {
                hintsRef[0].current.style.removeProperty("left");
            }
            if (hintsRef[1].current) {
                hintsRef[1].current.style.removeProperty("left");
            }
        }
    }, [direction]);
    useEffect(function () {
        fillSlider();
    }, [status, isDisabled, min, max]);
    useEffect(function () {
        if (typeof value !== "undefined") {
            var targetValue = isRange
                ? [
                    getValidValue({ value: value[0], min: min, max: max }),
                    getValidValue({ value: value[1], min: min, max: max })
                ]
                : getValidValue({ value: value, min: min, max: max });
            setCurrentValue(targetValue);
            if (isRange && inputsRef[0].current && inputsRef[1].current) {
                inputsRef[0].current.value = targetValue[0];
                inputsRef[1].current.value = targetValue[1];
            }
            else if (inputsRef[1].current) {
                inputsRef[1].current.value = String(targetValue);
            }
        }
    }, [isRange, value, min, max]);
    var handleChangeDebounce = useDebounce(function (event, _values) {
        onChange === null || onChange === void 0 ? void 0 : onChange(event, _values);
    }, 500);
    var setToggleAccessible = function (currentTarget) {
        if (inputsRef[1].current) {
            if (Number(currentTarget.value) <= 0) {
                inputsRef[1].current.style.zIndex = "2";
            }
            else {
                inputsRef[1].current.style.zIndex = "0";
            }
        }
    };
    var fillSlider = function () {
        if (inputsRef[1].current) {
            inputsRef[1].current.style.background = "linear-gradient(\n      to right,\n      " + theme.components.slider.background + " 0%,\n      " + theme.components.slider.background + " " + (fromPosition / rangeDistance) * 100 + "%,\n      " + theme.components.slider[!isDisabled
                ? "background" + (status.charAt(0).toUpperCase() + status.slice(1))
                : "backgroundDisabled"] + " " + (fromPosition / rangeDistance) * 100 + "%,\n      " + theme.components.slider[!isDisabled
                ? "background" + (status.charAt(0).toUpperCase() + status.slice(1))
                : "backgroundDisabled"] + " " + (toPosition / rangeDistance) * 100 + "%, \n      " + theme.components.slider.background + " " + (toPosition / rangeDistance) * 100 + "%, \n      " + theme.components.slider.background + " 100%)";
        }
    };
    var handleOnResetLeft = function (event) {
        if (defaultValue) {
            if (Array.isArray(defaultValue) &&
                Array.isArray(currentValue) &&
                isRange) {
                onChange === null || onChange === void 0 ? void 0 : onChange(event, [
                    defaultValue[0],
                    currentValue[1]
                ]);
                setCurrentValue(function (val) { return [defaultValue[0], val[1]]; });
                if (inputsRef[0].current) {
                    inputsRef[0].current.value = String(defaultValue[0]);
                }
            }
            else {
                onChange === null || onChange === void 0 ? void 0 : onChange(event, defaultValue);
                setCurrentValue(defaultValue);
            }
        }
        else if (!Array.isArray(defaultValue) && isRange) {
            onChange === null || onChange === void 0 ? void 0 : onChange(event, [
                min,
                currentValue[1]
            ]);
            setCurrentValue(function (val) { return [min, val[1]]; });
            if (inputsRef[0].current) {
                inputsRef[0].current.value = String(min);
            }
        }
        fillSlider();
    };
    var handleOnResetRight = function (event) {
        if (defaultValue) {
            if (Array.isArray(defaultValue) &&
                Array.isArray(currentValue) &&
                isRange) {
                onChange === null || onChange === void 0 ? void 0 : onChange(event, [
                    currentValue[0],
                    defaultValue[1]
                ]);
                setCurrentValue(function (val) { return [val[0], defaultValue[1]]; });
                if (inputsRef[1].current) {
                    inputsRef[1].current.value = String(defaultValue[1]);
                }
            }
            else if (inputsRef[1].current) {
                onChange === null || onChange === void 0 ? void 0 : onChange(event, defaultValue);
                setCurrentValue(defaultValue);
                inputsRef[1].current.value = String(defaultValue);
            }
        }
        else if (!Array.isArray(defaultValue) && isRange) {
            onChange === null || onChange === void 0 ? void 0 : onChange(event, [currentValue[0], max]);
            setCurrentValue(function (val) { return [val[0], max]; });
            if (inputsRef[1].current) {
                inputsRef[1].current.value = String(max);
            }
        }
        else if (inputsRef[1].current) {
            onChange === null || onChange === void 0 ? void 0 : onChange(event, min);
            setCurrentValue(min);
            inputsRef[1].current.value = String(min);
        }
    };
    var handleFromInput = function (event) {
        var fromSlider = inputsRef[0].current;
        var toSlider = inputsRef[1].current;
        if (fromSlider && toSlider && isRange) {
            var _a = __read(getParsed(fromSlider, toSlider, min), 2), from = _a[0], to = _a[1];
            var _value_1 = from > to ? to : from;
            fromSlider.value = String(_value_1);
            setCurrentValue(function (previousValue) { return [_value_1, previousValue[1]]; });
            handleChangeDebounce(event, [
                _value_1,
                currentValue[1]
            ]);
        }
    };
    var handleToInput = function (event) {
        var fromSlider = inputsRef[0].current;
        var toSlider = inputsRef[1].current;
        if (toSlider) {
            var _a = __read(getParsed(fromSlider, toSlider, min), 2), from = _a[0], to = _a[1];
            var _value_2 = from <= to ? to : from;
            toSlider.value = String(_value_2);
            setToggleAccessible(toSlider);
            fillSlider();
            if (isRange) {
                setCurrentValue(function (previousValue) { return [previousValue[0], _value_2]; });
                handleChangeDebounce(event, [
                    currentValue[0],
                    _value_2
                ]);
            }
            else {
                setCurrentValue(_value_2);
                handleChangeDebounce(event, _value_2);
            }
        }
    };
    var handleClick = function (event) {
        var _a = event.currentTarget.getBoundingClientRect(), x = _a.x, width = _a.width, y = _a.y;
        var clientX = event.clientX, clientY = event.clientY;
        var positionClick = 0;
        var valueClick = 0;
        if (direction === "horizontal") {
            positionClick = clientX - x;
            valueClick = Math.abs(Math.round(rangeDistance * (positionClick / width)));
        }
        else {
            positionClick = clientY - y;
            valueClick = Math.abs(Math.round(rangeDistance * (positionClick / width)) - max);
        }
        if (step) {
            valueClick = Math.floor((valueClick + step - 1) / step) * step;
        }
        if (valueClick >= min && valueClick <= max) {
            if (isRange) {
                var distanceValue1 = Math.abs(valueClick - currentValue[0]);
                var distanceValue2 = Math.abs(valueClick - currentValue[1]);
                if (distanceValue1 < distanceValue2 && inputsRef[0].current) {
                    inputsRef[0].current.value = String(valueClick);
                    onChange === null || onChange === void 0 ? void 0 : onChange(event, [
                        valueClick,
                        currentValue[1]
                    ]);
                    setCurrentValue(function (prevState) { return [valueClick, prevState[1]]; });
                }
                else if (inputsRef[1].current) {
                    inputsRef[1].current.value = String(valueClick);
                    onChange === null || onChange === void 0 ? void 0 : onChange(event, [
                        currentValue[0],
                        valueClick
                    ]);
                    setCurrentValue(function (prevState) { return [prevState[0], valueClick]; });
                }
            }
            else if (inputsRef[1].current) {
                inputsRef[1].current.value = String(valueClick);
                onChange === null || onChange === void 0 ? void 0 : onChange(event, valueClick);
                setCurrentValue(valueClick);
            }
        }
    };
    return {
        currentValue: currentValue,
        onResetLeft: handleOnResetLeft,
        onResetRight: handleOnResetRight,
        handleFromInput: handleFromInput,
        handleToInput: handleToInput,
        handleClick: handleClick
    };
}
