import { useEffect, useState } from "react";
/**
 * useLocalStorage is a custom hook that allows you to work with LocalStorage like useState.
 * It also syncs data between tabs in real-time.
 *
 * @param {string} key - A unique identifier for the localStorage entry.
 * @param {T} initialValue - The initial value for the localStorage entry.
 *
 * @returns {Array} An array where the first item is the stored value and the second item is a setter function.
 */
const useLocalStorage = <T>(
	key: string,
	initialValue: T,
): [T, (value: T) => void] => {
	// Store the initial value in localStorage or return the current value
	const [storedValue, setStoredValue] = useState<T>(() => {
		try {
			const item = window.localStorage.getItem(key);
			return item ? JSON.parse(item) : initialValue;
		} catch (error) {
			console.log(error);
			return initialValue;
		}
	});

	// Define a setter function for the storedValue
	const setValue = (value: T) => {
		try {
			const valueToStore = value instanceof Function ? value(storedValue) : value;
			setStoredValue(valueToStore);

			// Store the new value in localStorage
			window.localStorage.setItem(key, JSON.stringify(valueToStore));

			// Manually trigger a storage event
			const storageEvent = new StorageEvent("storage", {
				key: key,
				oldValue: JSON.stringify(storedValue),
				newValue: JSON.stringify(valueToStore),
				storageArea: localStorage,
			});
			window.dispatchEvent(storageEvent);
		} catch (error) {
			console.log(error);
		}
	};

	// Add an event listener for the storage event
	useEffect(() => {
		const handleStorageChange = (e: StorageEvent) => {
			if (e.key === key && e.newValue !== null) {
				setStoredValue(JSON.parse(e.newValue));
			}
		};

		window.addEventListener("storage", handleStorageChange);

		// Cleanup function
		return () => {
			window.removeEventListener("storage", handleStorageChange);
		};
	}, [key]);

	// Return the stored value and the setter function
	return [storedValue, setValue];
};

export default useLocalStorage;
