import isElectron from 'is-electron';
import { useEffect, useRef } from 'react';

import i18n from '/@/i18n/i18n';
import { openRestartRequiredToast } from '/@/renderer/features/settings/restart-toast';
import { useSettingsStore } from '/@/renderer/store/settings.store';
import { logFn } from '/@/renderer/utils/logger';
import { logMsg } from '/@/renderer/utils/logger-message';

// Synchronizes settings from the renderer store to the main process electron store
// on app initialization. If there are differences, it updates the main store and shows
// a restart required toast.
export const useSyncSettingsToMain = () => {
    const hasRunRef = useRef(false);

    useEffect(() => {
        if (hasRunRef.current) {
            return;
        }

        if (!isElectron() || !window.api.localSettings) {
            hasRunRef.current = true;
            return;
        }

        // Wait some before checking for differences to ensure the store is hydrated from localStorage
        const timeoutId = setTimeout(() => {
            if (hasRunRef.current) {
                return;
            }

            const settingsFromStore = useSettingsStore.getState();

            const settings = {
                general: settingsFromStore.general,
                hotkeys: settingsFromStore.hotkeys,
                lyrics: settingsFromStore.lyrics,
                playback: settingsFromStore.playback,
                window: settingsFromStore.window,
            };

            hasRunRef.current = true;

            const localSettings = window.api.localSettings;

            const settingsMappings: Array<{
                mainStoreKey: string;
                rendererValue: any;
            }> = [
                {
                    mainStoreKey: 'lyrics',
                    rendererValue: settings.lyrics.sources,
                },
                {
                    mainStoreKey: 'window_window_bar_style',
                    rendererValue: settings.window.windowBarStyle,
                },
                {
                    mainStoreKey: 'window_start_minimized',
                    rendererValue: settings.window.startMinimized,
                },
                {
                    mainStoreKey: 'window_exit_to_tray',
                    rendererValue: settings.window.exitToTray,
                },
                {
                    mainStoreKey: 'window_minimize_to_tray',
                    rendererValue: settings.window.minimizeToTray,
                },
                {
                    mainStoreKey: 'disable_auto_updates',
                    rendererValue: settings.window.disableAutoUpdate,
                },
                // For some reason after the application is updated, the release channel from the
                // renderer is always set to the latest channel. This causes an infinite update loop
                // {
                //     mainStoreKey: 'release_channel',
                //     rendererValue: settings.window.releaseChannel,
                // },
                {
                    mainStoreKey: 'window_enable_tray',
                    rendererValue: settings.window.tray,
                },
                {
                    mainStoreKey: 'password_store',
                    rendererValue: settings.general.passwordStore,
                },
                {
                    mainStoreKey: 'mediaSession',
                    rendererValue: settings.playback.mediaSession,
                },
                {
                    mainStoreKey: 'playbackType',
                    rendererValue: settings.playback.type,
                },
                {
                    mainStoreKey: 'global_media_hotkeys',
                    rendererValue: settings.hotkeys.globalMediaHotkeys,
                },
                {
                    mainStoreKey: 'enableNeteaseTranslation',
                    rendererValue: settings.lyrics.enableNeteaseTranslation,
                },
            ];

            // Compare and sync each setting
            (async () => {
                let hasDifferences = false;

                for (const mapping of settingsMappings) {
                    const mainValue = await localSettings.get(mapping.mainStoreKey);
                    const rendererValue = mapping.rendererValue;

                    const mainValueNormalized = mainValue === undefined ? null : mainValue;
                    const rendererValueNormalized =
                        rendererValue === undefined ? null : rendererValue;

                    if (
                        JSON.stringify(mainValueNormalized) !==
                        JSON.stringify(rendererValueNormalized)
                    ) {
                        hasDifferences = true;
                        logFn.warn(logMsg.system.settingsSynchronized, {
                            meta: {
                                mainStoreKey: mapping.mainStoreKey,
                                mainValue: mainValueNormalized,
                                rendererValue: rendererValueNormalized,
                            },
                        });
                        localSettings.set(mapping.mainStoreKey, rendererValue);
                    }
                }

                // Show restart toast if there were differences
                if (hasDifferences) {
                    openRestartRequiredToast(i18n.t('error.settingsSyncError'));
                }
            })();
        }, 5000);

        return () => {
            clearTimeout(timeoutId);
        };
        // Only run once on mount
    }, []);
};
