import { onUnmounted } from 'vue';

interface DebounceOptions {
	delay?: number;
	immediate?: boolean;
}

export function useDebounce() {
	const timers = new Map<string, number>();

	const debounce = (key: string, fn: () => void, options: DebounceOptions = {}) => {
		const { delay = 300 } = options;

		if (timers.has(key)) {
			clearTimeout(timers.get(key) as number);
		}

		const timer = setTimeout(() => {
			fn();
			timers.delete(key);
		}, delay) as unknown as number;

		timers.set(key, timer);
	};

	const clear = () => {
		timers.forEach((timer) => clearTimeout(timer));
		timers.clear();
	};

	onUnmounted(() => {
		clear();
	});

	return { debounce, clear };
}

export function createDebouncedFn(key: string, fn: () => void, delay = 300) {
	const timers = new Map<string, number>();

	return () => {
		if (timers.has(key)) {
			clearTimeout(timers.get(key) as number);
		}

		const timer = setTimeout(() => {
			fn();
			timers.delete(key);
		}, delay) as unknown as number;

		timers.set(key, timer);
	};
}
