'use client';

import React, { useState, useEffect, useCallback, ReactNode } from 'react';
import OfflineContext, { OfflineMode, defaultOfflineMode } from './OfflineContext';
import * as tauri from '@/lib/tauri';

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 {
            let userKey = encryptionKey;
            if (!userKey) {
                const storedKey = await tauri.getUserEncryptionKey(userId);
                if (storedKey) {
                    userKey = storedKey;
                } else {
                    throw new Error('No encryption key found for user');
                }
            }

            await tauri.dbInitialize(userId, userKey);

            setOfflineMode(prev => ({
                ...prev,
                isDatabaseInitialized: true,
                error: null
            }));

            return true;
        } catch (error) {
            console.error('Failed to initialize database:', error, 'userId:', userId, 'hasKey:', !!userKey);
            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>
    );
}
