import { useState, useCallback, useEffect } from 'react';

/**
 * Hook for persisting filter values in sessionStorage.
 * Values persist across page refreshes but clear when browser tab is closed.
 *
 * @param key - Unique key for this filter (will be prefixed with 'zeiterfassung_filter_')
 * @param defaultValue - Default value if nothing is stored
 * @returns [value, setValue] tuple similar to useState
 *
 * @example
 * const [department, setDepartment] = usePersistentFilter('shift_department', '');
 * const [selectedRole, setSelectedRole] = usePersistentFilter('shift_role', null);
 */
export function usePersistentFilter<T>(
  key: string,
  defaultValue: T
): [T, (value: T) => void] {
  const storageKey = `zeiterfassung_filter_${key}`;

  // Initialize state from sessionStorage or default
  const [value, setValue] = useState<T>(() => {
    try {
      const stored = sessionStorage.getItem(storageKey);
      if (stored !== null) {
        return JSON.parse(stored) as T;
      }
    } catch (error) {
      console.warn(`Failed to parse stored filter "${key}":`, error);
    }
    return defaultValue;
  });

  // Persist to sessionStorage whenever value changes
  const setPersistentValue = useCallback(
    (newValue: T) => {
      setValue(newValue);
      try {
        sessionStorage.setItem(storageKey, JSON.stringify(newValue));
      } catch (error) {
        console.warn(`Failed to persist filter "${key}":`, error);
      }
    },
    [storageKey, key]
  );

  return [value, setPersistentValue];
}

/**
 * Hook for persisting multiple related filters as an object.
 * Useful when you have several filters that should be grouped together.
 *
 * @param key - Unique key for this filter group
 * @param defaultFilters - Default filter values
 * @returns [filters, setFilter, resetFilters] tuple
 *
 * @example
 * const [filters, setFilter, resetFilters] = usePersistentFilters('shift_filters', {
 *   department: '',
 *   role: '',
 *   showInactive: false,
 * });
 * setFilter('department', '123');
 */
export function usePersistentFilters<T extends Record<string, unknown>>(
  key: string,
  defaultFilters: T
): [T, <K extends keyof T>(filterKey: K, value: T[K]) => void, () => void] {
  const storageKey = `zeiterfassung_filters_${key}`;

  const [filters, setFilters] = useState<T>(() => {
    try {
      const stored = sessionStorage.getItem(storageKey);
      if (stored !== null) {
        const parsed = JSON.parse(stored);
        // Merge with defaults to handle new filter keys
        return { ...defaultFilters, ...parsed };
      }
    } catch (error) {
      console.warn(`Failed to parse stored filters "${key}":`, error);
    }
    return defaultFilters;
  });

  // Update a single filter
  const setFilter = useCallback(
    <K extends keyof T>(filterKey: K, value: T[K]) => {
      setFilters((prev) => {
        const newFilters = { ...prev, [filterKey]: value };
        try {
          sessionStorage.setItem(storageKey, JSON.stringify(newFilters));
        } catch (error) {
          console.warn(`Failed to persist filters "${key}":`, error);
        }
        return newFilters;
      });
    },
    [storageKey, key]
  );

  // Reset all filters to defaults
  const resetFilters = useCallback(() => {
    setFilters(defaultFilters);
    try {
      sessionStorage.removeItem(storageKey);
    } catch (error) {
      console.warn(`Failed to clear filters "${key}":`, error);
    }
  }, [storageKey, key, defaultFilters]);

  return [filters, setFilter, resetFilters];
}

/**
 * Clear all Zeiterfassung filters from sessionStorage.
 * Useful for logout or reset scenarios.
 */
export function clearAllFilters(): void {
  try {
    const keysToRemove: string[] = [];
    for (let i = 0; i < sessionStorage.length; i++) {
      const key = sessionStorage.key(i);
      if (key?.startsWith('zeiterfassung_filter')) {
        keysToRemove.push(key);
      }
    }
    keysToRemove.forEach((key) => sessionStorage.removeItem(key));
  } catch (error) {
    console.warn('Failed to clear filters:', error);
  }
}
