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

interface UsePersistedStateOptions<T> {
    key: string;
    defaultValue: T;
    storage?: Storage;
    serialize?: (value: T) => string;
    deserialize?: (value: string) => T;
}

export function usePersistedState<T>({
    key,
    defaultValue,
    storage = localStorage,
    serialize = JSON.stringify,
    deserialize = JSON.parse
}: UsePersistedStateOptions<T>): [T, (value: T | ((prev: T) => T)) => void] {
    const [state, setState] = useState<T>(() => {
        try {
            const stored = storage.getItem(key);
            return stored ? deserialize(stored) : defaultValue;
        } catch {
            return defaultValue;
        }
    });

    useEffect(() => {
        try {
            storage.setItem(key, serialize(state));
        } catch {
            // Storage might be full or disabled
        }
    }, [key, state, storage, serialize]);

    return [state, setState];
}

// Specific hooks for common filter patterns
export function usePersistedFilter<T extends string>(key: string, defaultValue: T) {
    return usePersistedState<T>({ key: `filter:${key}`, defaultValue });
}

export function usePersistedSort(key: string, defaultValue: { field: string; direction: 'asc' | 'desc' }) {
    return usePersistedState({ key: `sort:${key}`, defaultValue });
}

export function usePersistedView(key: string, defaultValue: 'list' | 'grid' | 'calendar') {
    return usePersistedState({ key: `view:${key}`, defaultValue });
}

// Hook to persist multiple filters at once
interface FilterState {
    [key: string]: string | number | boolean | string[];
}

export function usePersistedFilters<T extends FilterState>(key: string, defaultFilters: T) {
    const [filters, setFilters] = usePersistedState<T>({
        key: `filters:${key}`,
        defaultValue: defaultFilters
    });

    const setFilter = useCallback(<K extends keyof T>(filterKey: K, value: T[K]) => {
        setFilters(prev => ({ ...prev, [filterKey]: value }));
    }, [setFilters]);

    const resetFilters = useCallback(() => {
        setFilters(defaultFilters);
    }, [setFilters, defaultFilters]);

    const hasActiveFilters = Object.keys(filters).some(
        k => JSON.stringify(filters[k]) !== JSON.stringify(defaultFilters[k])
    );

    return {
        filters,
        setFilters,
        setFilter,
        resetFilters,
        hasActiveFilters
    };
}

// Example usage:
// const [filter, setFilter] = usePersistedFilter('tasks-status', 'all');
// const { filters, setFilter, resetFilters } = usePersistedFilters('tasks', { status: 'all', priority: 'all' });
