import React from "react";
import Row from "../../layout/Row";
import { Info, Minus, Plus } from "lucide-react";
import twuiNumberfy from "../../utils/numberfy";
import { InputProps } from ".";

let pressInterval: any;
let pressTimeout: any;

type Props = Pick<InputProps<any>, "min" | "max" | "step"> & {
    setValue: React.Dispatch<React.SetStateAction<string>>;
    getNormalizedValue: (v: string) => void;
    buttonDownRef: React.MutableRefObject<boolean>;
    inputRef: React.RefObject<HTMLInputElement | null>;
};

/**
 * # Input Number Text Buttons
 */
export default function NumberInputButtons({
    getNormalizedValue,
    setValue,
    min,
    max,
    step,
    buttonDownRef,
    inputRef,
}: Props) {
    const PRESS_TRIGGER_TIMEOUT = 200;
    const DEFAULT_STEP = 1;

    function incrementDownPress() {
        window.clearTimeout(pressTimeout);
        pressTimeout = setTimeout(() => {
            buttonDownRef.current = true;
            pressInterval = setInterval(() => {
                increment();
            }, 50);
        }, PRESS_TRIGGER_TIMEOUT);
    }

    function incrementDownCancel() {
        buttonDownRef.current = false;
        window.clearTimeout(pressTimeout);
        window.clearInterval(pressInterval);
    }

    function decrementDownPress() {
        pressTimeout = setTimeout(() => {
            buttonDownRef.current = true;
            pressInterval = setInterval(() => {
                decrement();
            }, 50);
        }, PRESS_TRIGGER_TIMEOUT);
    }

    function decrementDownCancel() {
        buttonDownRef.current = false;
        window.clearTimeout(pressTimeout);
        window.clearInterval(pressInterval);
    }

    function increment() {
        const existingValue = inputRef.current?.value;
        const existingNumberValue = twuiNumberfy(existingValue);

        if (max && existingNumberValue >= twuiNumberfy(max)) {
            return setValue(String(max));
        } else if (min && existingNumberValue < twuiNumberfy(min)) {
            return setValue(String(min));
        } else {
            setValue(
                String(
                    existingNumberValue + twuiNumberfy(step || DEFAULT_STEP),
                ),
            );
        }
    }

    function decrement() {
        const existingValue = inputRef.current?.value;
        const existingNumberValue = twuiNumberfy(existingValue);

        if (min && existingNumberValue <= twuiNumberfy(min)) {
            setValue(String(min));
        } else {
            setValue(
                String(
                    existingNumberValue - twuiNumberfy(step || DEFAULT_STEP),
                ),
            );
        }
    }

    return (
        <Row className="flex-nowrap gap-1 -my-2 ml-auto -mr-2">
            <Row
                className="rounded-full w-8 h-8 cursor-pointer touch-none select-none justify-center"
                onClick={(e) => {
                    e.preventDefault();
                    decrement();
                }}
                onMouseDown={decrementDownPress}
                onTouchStart={decrementDownPress}
                onMouseUp={decrementDownCancel}
                onTouchEnd={decrementDownCancel}
            >
                <Minus size={20} />
            </Row>
            <Row
                className="rounded-full w-8 h-8 cursor-pointer touch-none select-none justify-center"
                onClick={(e) => {
                    e.preventDefault();
                    increment();
                }}
                onMouseDown={incrementDownPress}
                onTouchStart={incrementDownPress}
                onMouseUp={incrementDownCancel}
                onTouchEnd={incrementDownCancel}
            >
                <Plus size={20} />
            </Row>
        </Row>
    );
}
