import { useState, useEffect, useCallback } from 'react';
import { logDebug } from '../utils/errorReporter';

type SetValue<T> = T | ((val: T) => T);

interface StoredValueWithExpiry<T> {
  value: T;
  expires?: number; // Timestamp in milliseconds
}

/**
 * Hook for localStorage with optional expiration support
 * @param key - localStorage key
 * @param initialValue - Initial value if key doesn't exist
 * @param ttl - Time to live in milliseconds (optional)
 */
export function useLocalStorage<T>(
  key: string,
  initialValue: T,
  ttl?: number // Time to live in milliseconds
): [T, (value: SetValue<T>) => void, () => void] {
  
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      const item = window.localStorage.getItem(key);
      if (!item) return initialValue;
      
      const parsed: StoredValueWithExpiry<T> | T = JSON.parse(item);
      
      // Check if it has expiration metadata
      if (parsed && typeof parsed === 'object' && 'value' in parsed && 'expires' in parsed) {
        const withExpiry = parsed as StoredValueWithExpiry<T>;
        
        // Check expiration
        if (withExpiry.expires && withExpiry.expires < Date.now()) {
          logDebug(`localStorage key "${key}" expired, removing`, { 
            expiredAt: new Date(withExpiry.expires).toISOString(),
          });
          localStorage.removeItem(key);
          return initialValue;
        }
        
        return withExpiry.value ?? initialValue;
      }
      
      // Legacy format (no expiration)
      return parsed as T;
    } catch (error) {
      logDebug(`Error reading localStorage key "${key}"`, { error: error instanceof Error ? error.message : String(error) });
      return initialValue;
    }
  });

  
  
  const setValue = useCallback(
    (value: SetValue<T>) => {
      try {
        const valueToStore =
          value instanceof Function ? value(storedValue) : value;
        
        // Store with expiration if ttl is provided
        const toStore: StoredValueWithExpiry<T> | T = ttl
          ? {
              value: valueToStore,
              expires: Date.now() + ttl,
            }
          : valueToStore;
        
        setStoredValue(valueToStore);
        window.localStorage.setItem(key, JSON.stringify(toStore));
      } catch (error) {
        logDebug(`Error setting localStorage key "${key}"`, { error: error instanceof Error ? error.message : String(error) });
      }
    },
    [key, storedValue, ttl]
  );

  const removeValue = useCallback(() => {
    try {
      window.localStorage.removeItem(key);
      setStoredValue(initialValue);
    } catch (error) {
      logDebug(`Error removing localStorage key "${key}"`, { error: error instanceof Error ? error.message : String(error) });
    }
  }, [key, initialValue]);

  
  useEffect(() => {
    const handleStorageChange = (e: StorageEvent) => {
      if (e.key === key && e.newValue) {
        try {
          setStoredValue(JSON.parse(e.newValue));
        } catch (error) {
          logDebug(`Error parsing localStorage value for key "${key}"`, { error: error instanceof Error ? error.message : String(error) });
        }
      }
    };

    window.addEventListener('storage', handleStorageChange);
    return () => window.removeEventListener('storage', handleStorageChange);
  }, [key]);

  return [storedValue, setValue, removeValue];
}

