import { useState, useEffect, useCallback, createContext, useContext, ReactNode } from 'react';

const DRAFT_SEEN_KEY = 'seen_drafts';
const PROFILE_SEEN_KEY = 'seen_profiles';

// Helper to get seen items from localStorage
const getSeenItems = (key: string): Set<string> => {
    if (typeof window === 'undefined') return new Set();
    try {
        const stored = localStorage.getItem(key);
        return stored ? new Set(JSON.parse(stored)) : new Set();
    } catch {
        return new Set();
    }
};

// Helper to save seen items to localStorage
const saveSeenItems = (key: string, items: Set<string>) => {
    if (typeof window === 'undefined') return;
    try {
        localStorage.setItem(key, JSON.stringify(Array.from(items)));
    } catch (error) {
        console.error('Error saving to localStorage:', error);
    }
};

// ============== Context for Draft Seen ==============
interface DraftSeenContextType {
    seenDrafts: Set<string>;
    markDraftSeen: (draftId: string) => void;
    isDraftSeen: (draftId: string) => boolean;
    clearSeenDrafts: () => void;
}

const DraftSeenContext = createContext<DraftSeenContextType | null>(null);

export const DraftSeenProvider = ({ children }: { children: ReactNode }) => {
    const [seenDrafts, setSeenDrafts] = useState<Set<string>>(new Set());

    // Load from localStorage on mount
    useEffect(() => {
        setSeenDrafts(getSeenItems(DRAFT_SEEN_KEY));
    }, []);

    // Mark a draft as seen
    const markDraftSeen = useCallback((draftId: string) => {
        if (draftId == null || draftId === '') return;
        const id = String(draftId);
        setSeenDrafts(prev => {
            const newSet = new Set(prev);
            newSet.add(id);
            saveSeenItems(DRAFT_SEEN_KEY, newSet);
            return newSet;
        });
    }, []);

    // Check if a draft is seen
    const isDraftSeen = useCallback((draftId: string): boolean => {
        if (draftId == null || draftId === '') return false;
        return seenDrafts.has(String(draftId));
    }, [seenDrafts]);

    // Clear all seen drafts
    const clearSeenDrafts = useCallback(() => {
        setSeenDrafts(new Set());
        if (typeof window !== 'undefined') {
            localStorage.removeItem(DRAFT_SEEN_KEY);
        }
    }, []);

    return (
        <DraftSeenContext.Provider value={{ seenDrafts, markDraftSeen, isDraftSeen, clearSeenDrafts }}>
            {children}
        </DraftSeenContext.Provider>
    );
};

// Hook for managing draft seen status (uses context)
export const useLocalDraftSeen = () => {
    const context = useContext(DraftSeenContext);
    
    // Fallback for when not wrapped in provider (backward compatibility)
    const [seenDrafts, setSeenDrafts] = useState<Set<string>>(new Set());

    useEffect(() => {
        if (!context) {
            setSeenDrafts(getSeenItems(DRAFT_SEEN_KEY));
        }
    }, [context]);

    const markDraftSeen = useCallback((draftId: string) => {
        if (draftId == null || draftId === '') return;
        const id = String(draftId);
        if (context) {
            context.markDraftSeen(id);
        } else {
            setSeenDrafts(prev => {
                const newSet = new Set(prev);
                newSet.add(id);
                saveSeenItems(DRAFT_SEEN_KEY, newSet);
                return newSet;
            });
        }
    }, [context]);

    const isDraftSeen = useCallback((draftId: string): boolean => {
        if (draftId == null || draftId === '') return false;
        const id = String(draftId);
        if (context) {
            return context.isDraftSeen(id);
        }
        return seenDrafts.has(id);
    }, [context, seenDrafts]);

    const clearSeenDrafts = useCallback(() => {
        if (context) {
            context.clearSeenDrafts();
        } else {
            setSeenDrafts(new Set());
            if (typeof window !== 'undefined') {
                localStorage.removeItem(DRAFT_SEEN_KEY);
            }
        }
    }, [context]);

    if (context) {
        return context;
    }

    return { seenDrafts, markDraftSeen, isDraftSeen, clearSeenDrafts };
};

// ============== Context for Profile Seen ==============
interface ProfileSeenContextType {
    seenProfiles: Set<string>;
    markProfileSeen: (profileId: string) => void;
    isProfileSeen: (profileId: string) => boolean;
    clearSeenProfiles: () => void;
}

const ProfileSeenContext = createContext<ProfileSeenContextType | null>(null);

export const ProfileSeenProvider = ({ children }: { children: ReactNode }) => {
    const [seenProfiles, setSeenProfiles] = useState<Set<string>>(new Set());

    // Load from localStorage on mount
    useEffect(() => {
        setSeenProfiles(getSeenItems(PROFILE_SEEN_KEY));
    }, []);

    // Mark a profile as seen
    const markProfileSeen = useCallback((profileId: string) => {
        if (!profileId) return;
        setSeenProfiles(prev => {
            const newSet = new Set(prev);
            newSet.add(profileId);
            saveSeenItems(PROFILE_SEEN_KEY, newSet);
            return newSet;
        });
    }, []);

    // Check if a profile is seen
    const isProfileSeen = useCallback((profileId: string): boolean => {
        return seenProfiles.has(profileId);
    }, [seenProfiles]);

    // Clear all seen profiles
    const clearSeenProfiles = useCallback(() => {
        setSeenProfiles(new Set());
        if (typeof window !== 'undefined') {
            localStorage.removeItem(PROFILE_SEEN_KEY);
        }
    }, []);

    return (
        <ProfileSeenContext.Provider value={{ seenProfiles, markProfileSeen, isProfileSeen, clearSeenProfiles }}>
            {children}
        </ProfileSeenContext.Provider>
    );
};

// Hook for managing profile seen status (uses context)
export const useLocalProfileSeen = () => {
    const context = useContext(ProfileSeenContext);
    
    // Fallback for when not wrapped in provider (backward compatibility)
    const [seenProfiles, setSeenProfiles] = useState<Set<string>>(new Set());

    useEffect(() => {
        if (!context) {
            setSeenProfiles(getSeenItems(PROFILE_SEEN_KEY));
        }
    }, [context]);

    const markProfileSeen = useCallback((profileId: string) => {
        if (!profileId) return;
        if (context) {
            context.markProfileSeen(profileId);
        } else {
            setSeenProfiles(prev => {
                const newSet = new Set(prev);
                newSet.add(profileId);
                saveSeenItems(PROFILE_SEEN_KEY, newSet);
                return newSet;
            });
        }
    }, [context]);

    const isProfileSeen = useCallback((profileId: string): boolean => {
        if (context) {
            return context.isProfileSeen(profileId);
        }
        return seenProfiles.has(profileId);
    }, [context, seenProfiles]);

    const clearSeenProfiles = useCallback(() => {
        if (context) {
            context.clearSeenProfiles();
        } else {
            setSeenProfiles(new Set());
            if (typeof window !== 'undefined') {
                localStorage.removeItem(PROFILE_SEEN_KEY);
            }
        }
    }, [context]);

    if (context) {
        return context;
    }

    return { seenProfiles, markProfileSeen, isProfileSeen, clearSeenProfiles };
};

// Combined Provider for convenience
export const LocalSeenProvider = ({ children }: { children: ReactNode }) => {
    return (
        <DraftSeenProvider>
            <ProfileSeenProvider>
                {children}
            </ProfileSeenProvider>
        </DraftSeenProvider>
    );
};

export default useLocalDraftSeen;
