'use client';

import React, { useState, useEffect, useCallback, ReactNode } from 'react';
import OfflineContext, { OfflineMode, defaultOfflineMode } from './OfflineContext';

interface OfflineProviderProps {
    children: ReactNode;
}

export default function OfflineProvider({ children }: OfflineProviderProps) {
    const [offlineMode, setOfflineMode] = useState<OfflineMode>(defaultOfflineMode);

    const initializeDatabase = useCallback(async (userId: string, encryptionKey?: string): Promise<boolean> => {
        try {
            if (typeof window === 'undefined' || !(window as any).electron) {
                console.warn('Not running in Electron, offline mode not available');
                return false;
            }

            let userKey = encryptionKey;
            if (!userKey) {
                const storedKey = await (window as any).electron.getUserEncryptionKey(userId);
                if (storedKey) {
                    userKey = storedKey;
                } else {
                    const keyResult = await (window as any).electron.generateEncryptionKey(userId);
                    if (!keyResult.success) {
                        throw new Error(keyResult.error || 'Failed to generate encryption key');
                    }
                    userKey = keyResult.key;
                    await (window as any).electron.setUserEncryptionKey(userId, userKey);
                }
            }

            const result = await (window as any).electron.dbInitialize(userId, userKey);
            if (!result.success) {
                throw new Error(result.error || 'Failed to initialize database');
            }

            setOfflineMode(prev => ({
                ...prev,
                isDatabaseInitialized: true,
                error: null
            }));
            
            return true;
        } catch (error) {
            console.error('Failed to initialize database:', error);
            setOfflineMode(prev => ({
                ...prev,
                isDatabaseInitialized: false,
                error: error instanceof Error ? error.message : 'Failed to initialize database'
            }));
            return false;
        }
    }, []);

    const toggleOfflineMode = useCallback(() => {
        setOfflineMode((prev:OfflineMode):OfflineMode => {
            const newManuallyOffline:boolean = !prev.isManuallyOffline;
            const newIsOffline:boolean = newManuallyOffline || !prev.isNetworkOnline;

            return {
                ...prev,
                isManuallyOffline: newManuallyOffline,
                isOffline: newIsOffline
            };
        });
    }, []);

    const isCurrentlyOffline = useCallback((): boolean => {
        return offlineMode.isOffline;
    }, [offlineMode.isOffline]);

    useEffect(() => {
        const handleOnline = () => {
            setOfflineMode(prev => {
                const newIsOffline = prev.isManuallyOffline;

                return {
                    ...prev,
                    isNetworkOnline: true,
                    isOffline: newIsOffline
                };
            });
        };

        const handleOffline = () => {
            setOfflineMode(prev => {
                return {
                    ...prev,
                    isNetworkOnline: false,
                    isOffline: true
                };
            });
        };

        window.addEventListener('online', handleOnline);
        window.addEventListener('offline', handleOffline);

        return () => {
            window.removeEventListener('online', handleOnline);
            window.removeEventListener('offline', handleOffline);
        };
    }, []);

    const value = {
        offlineMode,
        setOfflineMode,
        toggleOfflineMode,
        initializeDatabase,
        isCurrentlyOffline
    };

    return (
        <OfflineContext.Provider value={value}>
            {children}
        </OfflineContext.Provider>
    );
}
