import { ThemeProvider } from "@/providers/themeProvider";
import { TooltipProvider } from "@/components/ui/tooltip";
import { AppContext } from "@/providers/appContextProvider";
import { DownloadState } from "@/types/download";
import { invoke } from "@tauri-apps/api/core";
import { useCallback, useEffect, useRef, useState } from "react";
import { arch, exeExtension } from "@tauri-apps/plugin-os";
import { downloadDir, join, resourceDir, tempDir } from "@tauri-apps/api/path";
import { useBasePathsStore, useCurrentVideoMetadataStore, useDownloaderPageStatesStore, useDownloadStatesStore, useKvPairsStatesStore, useSettingsPageStatesStore } from "@/services/store";
import { determineFileType, generateVideoId, isObjEmpty, parseProgressLine } from "@/utils";
import { Command } from "@tauri-apps/plugin-shell";
import { RawVideoInfo } from "@/types/video";
import { useDeleteDownloadState, useSaveDownloadState, useSavePlaylistInfo, useSaveVideoInfo, useUpdateDownloadFilePath, useUpdateDownloadStatus } from "@/services/mutations";
import { useQueryClient } from "@tanstack/react-query";
import { useFetchAllDownloadStates, useFetchAllkVPairs, useFetchAllSettings } from "@/services/queries";
import { config } from "@/config";
import * as fs from "@tauri-apps/plugin-fs";
import { useYtDlpUpdater } from "@/helpers/use-ytdlp-updater";
import { getVersion } from "@tauri-apps/api/app";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { listen } from "@tauri-apps/api/event";
import { WebSocketMessage } from "@/types/websocket";
import { useNavigate } from "react-router-dom";
import { platform } from "@tauri-apps/plugin-os";
import { useMacOsRegisterer } from "@/helpers/use-macos-registerer";
import useAppUpdater from "@/helpers/use-app-updater";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { toast } from "sonner";
import { useLogger } from "@/helpers/use-logger";
import { DownloadConfiguration } from "@/types/settings";
import { ulid } from "ulid";

export default function App({ children }: { children: React.ReactNode }) {
  const { data: downloadStates, isSuccess: isSuccessFetchingDownloadStates } = useFetchAllDownloadStates();
  const { data: settings, isSuccess: isSuccessFetchingSettings } = useFetchAllSettings();
  const { data: kvPairs, isSuccess: isSuccessFetchingKvPairs } = useFetchAllkVPairs();
  const [isSettingsStatePropagated, setIsSettingsStatePropagated] = useState(false);
  const [isKvPairsStatePropagated, setIsKvPairsStatePropagated] = useState(false);
  const globalDownloadStates = useDownloadStatesStore((state) => state.downloadStates);
  const setDownloadStates = useDownloadStatesStore((state) => state.setDownloadStates);
  const setPath = useBasePathsStore((state) => state.setPath);

  const ffmpegPath = useBasePathsStore((state) => state.ffmpegPath);
  const tempDownloadDirPath = useBasePathsStore((state) => state.tempDownloadDirPath);
  const downloadDirPath = useBasePathsStore((state) => state.downloadDirPath);

  const setSearchPid = useCurrentVideoMetadataStore((state) => state.setSearchPid);

  const setIsUsingDefaultSettings = useSettingsPageStatesStore((state) => state.setIsUsingDefaultSettings);
  const setSettingsKey = useSettingsPageStatesStore((state) => state.setSettingsKey);
  const appVersion = useSettingsPageStatesStore(state => state.appVersion);
  const ytDlpVersion = useSettingsPageStatesStore(state => state.ytDlpVersion);
  const setYtDlpVersion = useSettingsPageStatesStore((state) => state.setYtDlpVersion);
  const setIsFetchingYtDlpVersion = useSettingsPageStatesStore((state) => state.setIsFetchingYtDlpVersion);
  const setAppVersion = useSettingsPageStatesStore((state) => state.setAppVersion);
  const setIsFetchingAppVersion = useSettingsPageStatesStore((state) => state.setIsFetchingAppVersion);
  const YTDLP_AUTO_UPDATE = useSettingsPageStatesStore(state => state.settings.ytdlp_auto_update);
  const YTDLP_UPDATE_CHANNEL = useSettingsPageStatesStore(state => state.settings.ytdlp_update_channel);
  const APP_THEME = useSettingsPageStatesStore(state => state.settings.theme);
  const MAX_PARALLEL_DOWNLOADS = useSettingsPageStatesStore(state => state.settings.max_parallel_downloads);
  const MAX_RETRIES = useSettingsPageStatesStore(state => state.settings.max_retries);
  const DOWNLOAD_DIR = useSettingsPageStatesStore(state => state.settings.download_dir);
  const PREFER_VIDEO_OVER_PLAYLIST = useSettingsPageStatesStore(state => state.settings.prefer_video_over_playlist);
  const STRICT_DOWNLOADABILITY_CHECK = useSettingsPageStatesStore(state => state.settings.strict_downloadablity_check);
  const USE_PROXY = useSettingsPageStatesStore(state => state.settings.use_proxy);
  const PROXY_URL = useSettingsPageStatesStore(state => state.settings.proxy_url);
  const USE_RATE_LIMIT = useSettingsPageStatesStore(state => state.settings.use_rate_limit);
  const RATE_LIMIT = useSettingsPageStatesStore(state => state.settings.rate_limit);
  const VIDEO_FORMAT = useSettingsPageStatesStore(state => state.settings.video_format);
  const AUDIO_FORMAT = useSettingsPageStatesStore(state => state.settings.audio_format);
  const ALWAYS_REENCODE_VIDEO = useSettingsPageStatesStore(state => state.settings.always_reencode_video);
  const EMBED_VIDEO_METADATA = useSettingsPageStatesStore(state => state.settings.embed_video_metadata);
  const EMBED_AUDIO_METADATA = useSettingsPageStatesStore(state => state.settings.embed_audio_metadata);
  const EMBED_AUDIO_THUMBNAIL = useSettingsPageStatesStore(state => state.settings.embed_audio_thumbnail);
  const USE_COOKIES = useSettingsPageStatesStore(state => state.settings.use_cookies);
  const IMPORT_COOKIES_FROM = useSettingsPageStatesStore(state => state.settings.import_cookies_from);
  const COOKIES_BROWSER = useSettingsPageStatesStore(state => state.settings.cookies_browser);
  const COOKIES_FILE = useSettingsPageStatesStore(state => state.settings.cookies_file);
  const USE_SPONSORBLOCK = useSettingsPageStatesStore(state => state.settings.use_sponsorblock);
  const SPONSORBLOCK_MODE = useSettingsPageStatesStore(state => state.settings.sponsorblock_mode);
  const SPONSORBLOCK_REMOVE = useSettingsPageStatesStore(state => state.settings.sponsorblock_remove);
  const SPONSORBLOCK_MARK = useSettingsPageStatesStore(state => state.settings.sponsorblock_mark);
  const SPONSORBLOCK_REMOVE_CATEGORIES = useSettingsPageStatesStore(state => state.settings.sponsorblock_remove_categories);
  const SPONSORBLOCK_MARK_CATEGORIES = useSettingsPageStatesStore(state => state.settings.sponsorblock_mark_categories);
  const USE_ARIA2 = useSettingsPageStatesStore(state => state.settings.use_aria2);
  const USE_FORCE_INTERNET_PROTOCOL = useSettingsPageStatesStore(state => state.settings.use_force_internet_protocol);
  const FORCE_INTERNET_PROTOCOL = useSettingsPageStatesStore(state => state.settings.force_internet_protocol);
  const USE_CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.use_custom_commands);
  const CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.custom_commands);
  const FILENAME_TEMPLATE = useSettingsPageStatesStore(state => state.settings.filename_template);
  const DEBUG_MODE = useSettingsPageStatesStore(state => state.settings.debug_mode);
  const LOG_VERBOSE = useSettingsPageStatesStore(state => state.settings.log_verbose);
  const LOG_WARNING = useSettingsPageStatesStore(state => state.settings.log_warning);
  const LOG_PROGRESS = useSettingsPageStatesStore(state => state.settings.log_progress);

  const isErrored = useDownloaderPageStatesStore((state) => state.isErrored);
  const isErrorExpected = useDownloaderPageStatesStore((state) => state.isErrorExpected);
  const erroredDownloadId = useDownloaderPageStatesStore((state) => state.erroredDownloadId);
  const setIsErrored = useDownloaderPageStatesStore((state) => state.setIsErrored);
  const setIsErrorExpected = useDownloaderPageStatesStore((state) => state.setIsErrorExpected);
  const setErroredDownloadId = useDownloaderPageStatesStore((state) => state.setErroredDownloadId);

  const appWindow = getCurrentWebviewWindow()
  const navigate = useNavigate();
  const LOG = useLogger();
  const currentPlatform = platform();
  const { updateYtDlp } = useYtDlpUpdater();
  const { registerToMac } = useMacOsRegisterer();
  const { checkForAppUpdate } = useAppUpdater();
  const setKvPairsKey = useKvPairsStatesStore((state) => state.setKvPairsKey);
  const ytDlpUpdateLastCheck = useKvPairsStatesStore(state => state.kvPairs.ytdlp_update_last_check);
  const macOsRegisteredVersion = useKvPairsStatesStore(state => state.kvPairs.macos_registered_version);

  const queryClient = useQueryClient();
  const downloadStateSaver = useSaveDownloadState();
  const downloadStatusUpdater = useUpdateDownloadStatus();
  const downloadFilePathUpdater = useUpdateDownloadFilePath();
  const videoInfoSaver = useSaveVideoInfo();
  const downloadStateDeleter = useDeleteDownloadState();
  const playlistInfoSaver = useSavePlaylistInfo();

  const ongoingDownloads = globalDownloadStates.filter(state => state.download_status === 'downloading' || state.download_status === 'starting');
  const queuedDownloads = globalDownloadStates.filter(state => state.download_status === 'queued').sort((a, b) => a.queue_index! - b.queue_index!);

  const isProcessingQueueRef = useRef(false);
  const lastProcessedDownloadIdRef = useRef<string | null>(null);
  const hasRunYtDlpAutoUpdateRef = useRef(false);
  const isRegisteredToMacOsRef = useRef(false);

  const fetchVideoMetadata = async (url: string, formatId?: string, playlistIndex?: string, selectedSubtitles?: string | null, resumeState?: DownloadState, downloadConfig?: DownloadConfiguration): Promise<RawVideoInfo | null> => {
    try {
      const args = [url, '--dump-single-json', '--no-warnings'];
      if (formatId) args.push('--format', formatId);
      if (selectedSubtitles) args.push('--embed-subs', '--sub-lang', selectedSubtitles);
      if (playlistIndex) args.push('--playlist-items', playlistIndex);
      if (PREFER_VIDEO_OVER_PLAYLIST && !playlistIndex) args.push('--no-playlist');
      if (STRICT_DOWNLOADABILITY_CHECK && !formatId) args.push('--check-all-formats');
      if (STRICT_DOWNLOADABILITY_CHECK && formatId) args.push('--check-formats');

      if ((USE_CUSTOM_COMMANDS && CUSTOM_COMMANDS && downloadConfig?.custom_command) || resumeState?.custom_command) {
        let customCommandArgs = null;
        if (resumeState?.custom_command) {
          customCommandArgs = resumeState.custom_command;
        } else if (CUSTOM_COMMANDS.find(cmd => cmd.id === downloadConfig?.custom_command)) {
          let customCommand = CUSTOM_COMMANDS.find(cmd => cmd.id === downloadConfig?.custom_command);
          customCommandArgs = customCommand ? customCommand.args : '';
        }
        if (customCommandArgs && customCommandArgs.trim() !== '') args.push(...customCommandArgs.split(' '));
      }

      if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_PROXY && PROXY_URL) args.push('--proxy', PROXY_URL);
      if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_FORCE_INTERNET_PROTOCOL && FORCE_INTERNET_PROTOCOL) {
        if (FORCE_INTERNET_PROTOCOL === 'ipv4') {
          args.push('--force-ipv4');
        } else if (FORCE_INTERNET_PROTOCOL === 'ipv6') {
          args.push('--force-ipv6');
        }
      }
      if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_COOKIES) {
        if (IMPORT_COOKIES_FROM === 'browser' && COOKIES_BROWSER) {
          args.push('--cookies-from-browser', COOKIES_BROWSER);
        } else if (IMPORT_COOKIES_FROM === 'file' && COOKIES_FILE) {
          args.push('--cookies', COOKIES_FILE);
        }
      }
      if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && (USE_SPONSORBLOCK || (resumeState?.sponsorblock_remove || resumeState?.sponsorblock_mark))) {
        if (SPONSORBLOCK_MODE === 'remove' || resumeState?.sponsorblock_remove) {
          let sponsorblockRemove = resumeState?.sponsorblock_remove || (SPONSORBLOCK_REMOVE === 'custom' ? (
          SPONSORBLOCK_REMOVE_CATEGORIES.length > 0 ? SPONSORBLOCK_REMOVE_CATEGORIES.join(',') : 'default'
          ) : (SPONSORBLOCK_REMOVE));
          args.push('--sponsorblock-remove', sponsorblockRemove);
        } else if (SPONSORBLOCK_MODE === 'mark' || resumeState?.sponsorblock_mark) {
          let sponsorblockMark = resumeState?.sponsorblock_mark || (SPONSORBLOCK_MARK === 'custom' ? (
          SPONSORBLOCK_MARK_CATEGORIES.length > 0 ? SPONSORBLOCK_MARK_CATEGORIES.join(',') : 'default'
          ) : (SPONSORBLOCK_MARK));
          args.push('--sponsorblock-mark', sponsorblockMark);
        }
      };
      const command = Command.sidecar('binaries/yt-dlp', args);

      let jsonOutput = '';

      return new Promise<RawVideoInfo | null>((resolve) => {
        command.stdout.on('data', line => {
          jsonOutput += line;
        });

        command.on('close', async (data) => {
          if (data.code !== 0) {
            console.error(`yt-dlp failed to fetch metadata with code ${data.code}`);
            LOG.error('NEODLP', `yt-dlp exited with code ${data.code} while fetching metadata for URL: ${url} (ignore if you manually cancelled)`);
            resolve(null);
          } else {
            try {
              const matchedJson = jsonOutput.match(/{.*}/);
              if (!matchedJson) {
                console.error(`Failed to match JSON: ${jsonOutput}`);
                LOG.error('NEODLP', `Failed to parse metadata JSON for URL: ${url})`);
                resolve(null);
                return;
              }
              const parsedJson: RawVideoInfo = JSON.parse(matchedJson[0]);
              resolve(parsedJson);
            }
            catch (e) {
              console.error(`Failed to parse JSON: ${e}`);
              LOG.error('NEODLP', `Failed to parse metadata JSON for URL: ${url}) with error: ${e}`);
              resolve(null);
            }
          }
        });

        command.on('error', error => {
          console.error(`Error fetching metadata: ${error}`);
          LOG.error('NEODLP', `Error occurred while fetching metadata for URL: ${url} : ${error}`);
          resolve(null);
        });

        LOG.info('NEODLP', `Fetching metadata for URL: ${url}, with args: ${args.join(' ')}`);
        command.spawn().then(child => {
          setSearchPid(child.pid);
        }).catch(e => {
          console.error(`Failed to spawn command: ${e}`);
          LOG.error('NEODLP', `Failed to spawn yt-dlp process for fetching metadata for URL: ${url} : ${e}`);
          resolve(null);
        });
      });
    } catch (e) {
      console.error(`Failed to fetch metadata: ${e}`);
      LOG.error('NEODLP', `Failed to fetch metadata for URL: ${url} : ${e}`);
      return null;
    }
  };

  const startDownload = async (url: string, selectedFormat: string, downloadConfig: DownloadConfiguration, selectedSubtitles?: string | null, resumeState?: DownloadState, playlistItems?: string) => {
    LOG.info('NEODLP', `Initiating yt-dlp download for URL: ${url}`);
    // set error states to default
    setIsErrored(false);
    setIsErrorExpected(false);
    setErroredDownloadId(null);

    console.log('Starting download:', { url, selectedFormat, downloadConfig, selectedSubtitles, resumeState, playlistItems });
    if (!ffmpegPath || !tempDownloadDirPath || !downloadDirPath) {
      console.error('FFmpeg or download paths not found');
      return;
    }

    const isPlaylist = (playlistItems && typeof playlistItems === 'string') || (resumeState?.playlist_id && resumeState?.playlist_index) ? true : false;
    const playlistIndex = isPlaylist ? (resumeState?.playlist_index?.toString() || playlistItems) : null;
    let videoMetadata = await fetchVideoMetadata(url, selectedFormat, isPlaylist && playlistIndex && typeof playlistIndex === 'string' ? playlistIndex : undefined, selectedSubtitles, resumeState);
    if (!videoMetadata) {
      console.error('Failed to fetch video metadata');
      toast.error("Download Failed", {
        description: "yt-dlp failed to fetch video metadata. Please try again later.",
      });
      return;
    }

    console.log('Video Metadata:', videoMetadata);
    videoMetadata = isPlaylist ? videoMetadata.entries[0] : videoMetadata;

    const fileType = determineFileType(videoMetadata.vcodec, videoMetadata.acodec);

    if (fileType !== 'unknown' && (VIDEO_FORMAT !== 'auto' || AUDIO_FORMAT !== 'auto')) {
      if (VIDEO_FORMAT !== 'auto' && (fileType === 'video+audio' || fileType === 'video')) videoMetadata.ext = VIDEO_FORMAT;
      if (AUDIO_FORMAT !== 'auto' && fileType === 'audio') videoMetadata.ext = AUDIO_FORMAT;
    }

    let configOutputFormat = null;
    if (downloadConfig.output_format && downloadConfig.output_format !== 'auto') {
      videoMetadata.ext = downloadConfig.output_format;
      configOutputFormat = downloadConfig.output_format;
    }
    if (resumeState && resumeState.output_format) videoMetadata.ext = resumeState.output_format;

    const videoId = resumeState?.video_id || generateVideoId(videoMetadata.id, videoMetadata.webpage_url_domain);
    const playlistId = isPlaylist ? (resumeState?.playlist_id || generateVideoId(videoMetadata.playlist_id, videoMetadata.webpage_url_domain)) : null;
    const downloadId = resumeState?.download_id || ulid() /*generateDownloadId(videoMetadata.id, videoMetadata.webpage_url_domain)*/;
    // const tempDownloadPathForYtdlp = await join(tempDownloadDirPath, `${downloadId}_${selectedFormat}.%(ext)s`);
    // const tempDownloadPath = await join(tempDownloadDirPath, `${downloadId}_${selectedFormat}.${videoMetadata.ext}`);
    // let downloadFilePath = resumeState?.filepath || await join(downloadDirPath, sanitizeFilename(`${videoMetadata.title}_${videoMetadata.resolution || 'unknown'}[${videoMetadata.id}].${videoMetadata.ext}`));
    let downloadFilePath: string | null = null;
    let processPid: number | null = null;
    const args = [
      url,
      '--newline',
      '--progress-template',
      'status:%(progress.status)s,progress:%(progress._percent_str)s,speed:%(progress.speed)f,downloaded:%(progress.downloaded_bytes)d,total:%(progress.total_bytes)d,eta:%(progress.eta)d',
      '--paths',
      `temp:${tempDownloadDirPath}`,
      '--paths',
      `home:${downloadDirPath}`,
      '--output',
      `${FILENAME_TEMPLATE}[${downloadId}].%(ext)s`,
      '--windows-filenames',
      '--restrict-filenames',
      '--exec',
      'after_move:echo Finalpath: {}',
      '--format',
      selectedFormat,
      '--no-mtime',
      '--retries',
      MAX_RETRIES.toString(),
    ];

    if (currentPlatform === 'macos') {
      args.push('--ffmpeg-location', '/Applications/NeoDLP.app/Contents/MacOS');
    }

    if (!DEBUG_MODE || (DEBUG_MODE && !LOG_WARNING)) {
      args.push('--no-warnings');
    }

    if (DEBUG_MODE && LOG_VERBOSE) {
      args.push('--verbose');
    }

    if (selectedSubtitles) {
      args.push('--embed-subs', '--sub-lang', selectedSubtitles);
    }

    if (isPlaylist && playlistIndex && typeof playlistIndex === 'string') {
      args.push('--playlist-items', playlistIndex);
    }

    let customCommandArgs = null;
    if ((USE_CUSTOM_COMMANDS && CUSTOM_COMMANDS && downloadConfig.custom_command) || resumeState?.custom_command) {
        if (resumeState?.custom_command) {
            customCommandArgs = resumeState.custom_command;
        } else if (CUSTOM_COMMANDS.find(cmd => cmd.id === downloadConfig.custom_command)) {
            let customCommand = CUSTOM_COMMANDS.find(cmd => cmd.id === downloadConfig.custom_command);
            customCommandArgs = customCommand ? customCommand.args : '';
        }

        if (customCommandArgs && customCommandArgs.trim() !== '') args.push(...customCommandArgs.split(' '));
    }

    let outputFormat = null;
    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && ((fileType !== 'unknown' && (VIDEO_FORMAT !== 'auto' || AUDIO_FORMAT !== 'auto')) || configOutputFormat || resumeState?.output_format)) {
        const format = resumeState?.output_format || configOutputFormat;

        if (format) {
            outputFormat = format;
        } else if (fileType === 'audio' && AUDIO_FORMAT !== 'auto') {
            outputFormat = AUDIO_FORMAT;
        } else if ((fileType === 'video' || fileType === 'video+audio') && VIDEO_FORMAT !== 'auto') {
            outputFormat = VIDEO_FORMAT;
        }

        const recodeOrRemux = ALWAYS_REENCODE_VIDEO ? '--recode-video' : '--remux-video';
        const formatToUse = format || VIDEO_FORMAT;

        // Handle video+audio
        if (fileType === 'video+audio' && (VIDEO_FORMAT !== 'auto' || format)) {
            args.push(ALWAYS_REENCODE_VIDEO ? '--recode-video' : '--merge-output-format', formatToUse);
        }
        // Handle video only
        else if (fileType === 'video' && (VIDEO_FORMAT !== 'auto' || format)) {
            args.push(recodeOrRemux, formatToUse);
        }
        // Handle audio only
        else if (fileType === 'audio' && (AUDIO_FORMAT !== 'auto' || format)) {
            args.push('--extract-audio', '--audio-format', format || AUDIO_FORMAT);
        }
        // Handle unknown filetype
        else if (fileType === 'unknown' && format) {
            if (['mkv', 'mp4', 'webm'].includes(format)) {
                args.push(recodeOrRemux, formatToUse);
            } else if (['mp3', 'm4a', 'opus'].includes(format)) {
                args.push('--extract-audio', '--audio-format', format);
            }
        }
    }

    let embedMetadata = 0;
    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && (downloadConfig.embed_metadata || resumeState?.embed_metadata || EMBED_VIDEO_METADATA || EMBED_AUDIO_METADATA)) {
        const shouldEmbedForVideo = (fileType === 'video+audio' || fileType === 'video') && (downloadConfig.embed_metadata || resumeState?.embed_metadata || (EMBED_VIDEO_METADATA && downloadConfig.embed_metadata === null));
        const shouldEmbedForAudio = fileType === 'audio' && (downloadConfig.embed_metadata || resumeState?.embed_metadata || (EMBED_AUDIO_METADATA && downloadConfig.embed_metadata === null));
        const shouldEmbedForUnknown = fileType === 'unknown' && (downloadConfig.embed_metadata || resumeState?.embed_metadata);

        if (shouldEmbedForUnknown || shouldEmbedForVideo || shouldEmbedForAudio) {
            embedMetadata = 1;
            args.push('--embed-metadata');
        }
    }

    let embedThumbnail = 0;
    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && (downloadConfig.embed_thumbnail || resumeState?.embed_thumbnail || (fileType === 'audio' && EMBED_AUDIO_THUMBNAIL && downloadConfig.embed_thumbnail === null))) {
      embedThumbnail = 1;
      args.push('--embed-thumbnail');
    }

    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_PROXY && PROXY_URL) {
      args.push('--proxy', PROXY_URL);
    }

    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_RATE_LIMIT && RATE_LIMIT) {
      args.push('--limit-rate', `${RATE_LIMIT}`);
    }

    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_FORCE_INTERNET_PROTOCOL && FORCE_INTERNET_PROTOCOL) {
      if (FORCE_INTERNET_PROTOCOL === 'ipv4') {
        args.push('--force-ipv4');
      } else if (FORCE_INTERNET_PROTOCOL === 'ipv6') {
        args.push('--force-ipv6');
      }
    }

    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && USE_COOKIES) {
      if (IMPORT_COOKIES_FROM === 'browser' && COOKIES_BROWSER) {
        args.push('--cookies-from-browser', COOKIES_BROWSER);
      } else if (IMPORT_COOKIES_FROM === 'file' && COOKIES_FILE) {
        args.push('--cookies', COOKIES_FILE);
      }
    }

    let sponsorblockRemove = null;
    let sponsorblockMark = null;
    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && (USE_SPONSORBLOCK || (resumeState?.sponsorblock_remove || resumeState?.sponsorblock_mark))) {
      if (SPONSORBLOCK_MODE === 'remove' || resumeState?.sponsorblock_remove) {
        sponsorblockRemove = resumeState?.sponsorblock_remove || (SPONSORBLOCK_REMOVE === 'custom' ? (
          SPONSORBLOCK_REMOVE_CATEGORIES.length > 0 ? SPONSORBLOCK_REMOVE_CATEGORIES.join(',') : 'default'
        ) : (SPONSORBLOCK_REMOVE));
        args.push('--sponsorblock-remove', sponsorblockRemove);
      } else if (SPONSORBLOCK_MODE === 'mark' || resumeState?.sponsorblock_mark) {
        sponsorblockMark = resumeState?.sponsorblock_mark || (SPONSORBLOCK_MARK === 'custom' ? (
          SPONSORBLOCK_MARK_CATEGORIES.length > 0 ? SPONSORBLOCK_MARK_CATEGORIES.join(',') : 'default'
        ) : (SPONSORBLOCK_MARK));
        args.push('--sponsorblock-mark', sponsorblockMark);
      }
    }

    let useAria2 = 0;
    if ((!USE_CUSTOM_COMMANDS && !resumeState?.custom_command) && (USE_ARIA2 || resumeState?.use_aria2)) {
      useAria2 = 1;
      args.push(
        '--downloader', 'aria2c',
        '--downloader', 'dash,m3u8:native',
        '--downloader-args', 'aria2c:-c -j 16 -x 16 -s 16 -k 1M --check-certificate=false'
      );
      LOG.warning('NEODLP', `Looks like you are using aria2 for this yt-dlp download: ${downloadId}. Make sure aria2 is installed on your system if you are on macOS for this to work. Also, pause/resume might not work as expected especially on windows (using aria2 is not recommended for most downloads).`);
    }

    if (resumeState || (!USE_CUSTOM_COMMANDS && USE_ARIA2)) {
      args.push('--continue');
    } else {
      args.push('--no-continue');
    }

    console.log('Starting download with args:', args);
    const command = Command.sidecar('binaries/yt-dlp', args);

    command.on('close', async (data) => {
      if (data.code !== 0) {
        console.error(`Download failed with code ${data.code}`);
        LOG.error(`YT-DLP Download ${downloadId}`, `yt-dlp exited with code ${data.code} (ignore if you manually paused or cancelled the download)`);
        if (!isErrorExpected) {
          setIsErrored(true);
          setErroredDownloadId(downloadId);
        }
      } else {
        LOG.info(`YT-DLP Download ${downloadId}`, `yt-dlp exited with code ${data.code}`);
      }
    });

    command.on('error', error => {
      console.error(`Error: ${error}`);
      LOG.error(`YT-DLP Download ${downloadId}`, `Error occurred: ${error}`);
      setIsErrored(true);
      setErroredDownloadId(downloadId);
    });

    command.stdout.on('data', line => {
      if (line.startsWith('status:') || line.startsWith('[#')) {
        console.log(line);
        if (DEBUG_MODE && LOG_PROGRESS) LOG.progress(`YT-DLP Download ${downloadId}`, line);
        const currentProgress = parseProgressLine(line);
        const state: DownloadState = {
          download_id: downloadId,
          download_status: 'downloading',
          video_id: videoId,
          format_id: selectedFormat,
          subtitle_id: selectedSubtitles || null,
          queue_index: null,
          playlist_id: playlistId,
          playlist_index: playlistIndex ? Number(playlistIndex) : null,
          title: videoMetadata.title,
          url: url,
          host: videoMetadata.webpage_url_domain,
          thumbnail: videoMetadata.thumbnail || null,
          channel: videoMetadata.channel || null,
          duration_string: videoMetadata.duration_string || null,
          release_date: videoMetadata.release_date || null,
          view_count: videoMetadata.view_count || null,
          like_count: videoMetadata.like_count || null,
          playlist_title: videoMetadata.playlist_title,
          playlist_url: videoMetadata.playlist_webpage_url,
          playlist_n_entries: videoMetadata.playlist_count || videoMetadata.n_entries,
          playlist_channel: videoMetadata.playlist_channel || null,
          resolution: videoMetadata.resolution || null,
          ext: videoMetadata.ext || null,
          abr: videoMetadata.abr || null,
          vbr: videoMetadata.vbr || null,
          acodec: videoMetadata.acodec || null,
          vcodec: videoMetadata.vcodec || null,
          dynamic_range: videoMetadata.dynamic_range || null,
          process_id: processPid,
          status: currentProgress.status || null,
          progress: currentProgress.progress || null,
          total: currentProgress.total || null,
          downloaded: currentProgress.downloaded || null,
          speed: currentProgress.speed || null,
          eta: currentProgress.eta || null,
          filepath: downloadFilePath,
          filetype: determineFileType(videoMetadata.vcodec, videoMetadata.acodec) || null,
          filesize: videoMetadata.filesize_approx || null,
          output_format: outputFormat,
          embed_metadata: embedMetadata,
          embed_thumbnail: embedThumbnail,
          sponsorblock_remove: sponsorblockRemove,
          sponsorblock_mark: sponsorblockMark,
          use_aria2: useAria2,
          custom_command: customCommandArgs,
          queue_config: null
        };
        downloadStateSaver.mutate(state, {
          onSuccess: (data) => {
            console.log("Download State saved successfully:", data);
            queryClient.invalidateQueries({ queryKey: ['download-states'] });
          },
          onError: (error) => {
            console.error("Failed to save download state:", error);
          }
        })
      } else {
        console.log(line);
        if (line.trim() !== '') LOG.info(`YT-DLP Download ${downloadId}`, line);

        if (line.startsWith('Finalpath: ')) {
            downloadFilePath = line.replace('Finalpath: ', '').trim().replace(/^"|"$/g, '');
            const downloadedFileExt = downloadFilePath.split('.').pop();

            // Update completion status after a short delay to ensure database states are propagated correctly
            console.log(`Download completed with ID: ${downloadId}, updating filepath and status after 2s delay...`);
            setTimeout(() => {
                LOG.info('NEODLP', `yt-dlp download completed with id: ${downloadId}`);
                downloadFilePathUpdater.mutate({ download_id: downloadId, filepath: downloadFilePath as string, ext: downloadedFileExt as string }, {
                    onSuccess: (data) => {
                        console.log("Download filepath updated successfully:", data);
                        queryClient.invalidateQueries({ queryKey: ['download-states'] });
                    },
                    onError: (error) => {
                        console.error("Failed to update download filepath:", error);
                    }
                });

                downloadStatusUpdater.mutate({ download_id: downloadId, download_status: 'completed' }, {
                    onSuccess: (data) => {
                        console.log("Download status updated successfully:", data);
                        queryClient.invalidateQueries({ queryKey: ['download-states'] });
                    },
                    onError: (error) => {
                        console.error("Failed to update download status:", error);
                    }
                });
            }, 2000);
        }
      }
    });

    try {
      videoInfoSaver.mutate({
        video_id: videoId,
        title: videoMetadata.title,
        url: url,
        host: videoMetadata.webpage_url_domain,
        thumbnail: videoMetadata.thumbnail || null,
        channel: videoMetadata.channel || videoMetadata.uploader || null,
        duration_string: videoMetadata.duration_string || null,
        release_date: videoMetadata.release_date || null,
        view_count: videoMetadata.view_count || null,
        like_count: videoMetadata.like_count || null
      }, {
        onSuccess: (data) => {
          console.log("Video Info saved successfully:", data);
          if (isPlaylist) {
            playlistInfoSaver.mutate({
              playlist_id: playlistId ? playlistId : '',
              playlist_title: videoMetadata.playlist_title,
              playlist_url: videoMetadata.playlist_webpage_url,
              playlist_n_entries: videoMetadata.playlist_count || videoMetadata.n_entries,
              playlist_channel: videoMetadata.playlist_channel || null
            }, {
              onSuccess: (data) => {
                console.log("Playlist Info saved successfully:", data);
              },
              onError: (error) => {
                console.error("Failed to save playlist info:", error);
              }
            })
          }
          const state: DownloadState = {
            download_id: downloadId,
            download_status: (!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) ? 'starting' : 'queued',
            video_id: videoId,
            format_id: selectedFormat,
            subtitle_id: selectedSubtitles || null,
            queue_index: (!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) ? null : (queuedDownloads?.length || 0),
            playlist_id: playlistId,
            playlist_index: playlistIndex ? Number(playlistIndex) : null,
            title: videoMetadata.title,
            url: url,
            host: videoMetadata.webpage_url_domain,
            thumbnail: videoMetadata.thumbnail || null,
            channel: videoMetadata.channel || null,
            duration_string: videoMetadata.duration_string || null,
            release_date: videoMetadata.release_date || null,
            view_count: videoMetadata.view_count || null,
            like_count: videoMetadata.like_count || null,
            playlist_title: videoMetadata.playlist_title,
            playlist_url: videoMetadata.playlist_webpage_url,
            playlist_n_entries: videoMetadata.playlist_count || videoMetadata.n_entries,
            playlist_channel: videoMetadata.playlist_channel || null,
            resolution: resumeState?.resolution || null,
            ext: resumeState?.ext || null,
            abr: resumeState?.abr || null,
            vbr: resumeState?.vbr || null,
            acodec: resumeState?.acodec || null,
            vcodec: resumeState?.vcodec || null,
            dynamic_range: resumeState?.dynamic_range || null,
            process_id: resumeState?.process_id || null,
            status: resumeState?.status || null,
            progress: resumeState?.progress || null,
            total: resumeState?.total || null,
            downloaded: resumeState?.downloaded || null,
            speed: resumeState?.speed || null,
            eta: resumeState?.eta || null,
            filepath: downloadFilePath,
            filetype: resumeState?.filetype || null,
            filesize: resumeState?.filesize || null,
            output_format: resumeState?.output_format || null,
            embed_metadata: resumeState?.embed_metadata || 0,
            embed_thumbnail: resumeState?.embed_thumbnail || 0,
            sponsorblock_remove: resumeState?.sponsorblock_remove || null,
            sponsorblock_mark: resumeState?.sponsorblock_mark || null,
            use_aria2: resumeState?.use_aria2 || 0,
            custom_command: resumeState?.custom_command || null,
            queue_config: resumeState?.queue_config || ((!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) ? null : JSON.stringify(downloadConfig))
          }
          downloadStateSaver.mutate(state, {
            onSuccess: (data) => {
              console.log("Download State saved successfully:", data);
              queryClient.invalidateQueries({ queryKey: ['download-states'] });
            },
            onError: (error) => {
              console.error("Failed to save download state:", error);
            }
          })
        },
        onError: (error) => {
          console.error("Failed to save video info:", error);
        }
      })

      if (!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) {
        LOG.info('NEODLP', `Starting yt-dlp download with args: ${args.join(' ')}`);
        if(!DEBUG_MODE || (DEBUG_MODE && !LOG_PROGRESS)) LOG.warning('NEODLP', `Progress logs are hidden. Enable 'Debug Mode > Log Progress' in Settings to unhide.`);
        const child = await command.spawn();
        processPid = child.pid;
        return Promise.resolve();
      } else {
        console.log("Download is queued, not starting immediately.");
        LOG.info('NEODLP', `Download queued with id: ${downloadId}`);
        return Promise.resolve();
      }
    } catch (e) {
      console.error(`Failed to start download: ${e}`);
      LOG.error('NEODLP', `Failed to start download for URL: ${url} with error: ${e}`);
      throw e;
    }
  };

  const pauseDownload = async (downloadState: DownloadState) => {
    try {
      LOG.info('NEODLP', `Pausing yt-dlp download with id: ${downloadState.download_id} (as per user request)`);
      if ((downloadState.download_status === 'downloading' && downloadState.process_id) || (downloadState.download_status === 'starting' && downloadState.process_id)) {
        setIsErrorExpected(true);  // Set error expected to true to handle UI state
        console.log("Killing process with PID:", downloadState.process_id);
        await invoke('kill_all_process', { pid: downloadState.process_id });
      }
      downloadStatusUpdater.mutate({ download_id: downloadState.download_id, download_status: 'paused' }, {
        onSuccess: (data) => {
          console.log("Download status updated successfully:", data);
          queryClient.invalidateQueries({ queryKey: ['download-states'] });

          /* re-check if the download is properly paused (if not try again after a small delay)
          as the pause opertion happens within high throughput of operations and have a high chgance of failure.
          */
          if (isSuccessFetchingDownloadStates && downloadStates.find(state => state.download_id === downloadState.download_id)?.download_status !== 'paused') {
            console.log("Download status not updated to paused yet, retrying...");
            setTimeout(() => {
              downloadStatusUpdater.mutate({ download_id: downloadState.download_id, download_status: 'paused' }, {
                onSuccess: (data) => {
                  console.log("Download status updated successfully on retry:", data);
                  queryClient.invalidateQueries({ queryKey: ['download-states'] });
                },
                onError: (error) => {
                  console.error("Failed to update download status:", error);
                }
              });
            }, 200);
          }

          // Reset the processing flag to ensure queue can be processed
          isProcessingQueueRef.current = false;

          // Process the queue after a short delay to ensure state is updated
          setTimeout(() => {
            processQueuedDownloads();
          }, 1000);
        },
        onError: (error) => {
          console.error("Failed to update download status:", error);
        }
      })
      return Promise.resolve();
    } catch (e) {
      console.error(`Failed to pause download: ${e}`);
      LOG.error('NEODLP', `Failed to pause download with id: ${downloadState.download_id} with error: ${e}`);
      isProcessingQueueRef.current = false;
      throw e;
    }
  };

  const resumeDownload = async (downloadState: DownloadState) => {
    try {
      LOG.info('NEODLP', `Resuming yt-dlp download with id: ${downloadState.download_id} (as per user request)`);
      await startDownload(
        downloadState.playlist_id && downloadState.playlist_index ? downloadState.playlist_url : downloadState.url,
        downloadState.format_id,
        downloadState.queue_config ? JSON.parse(downloadState.queue_config) : {
          output_format: null,
          embed_metadata: null,
          embed_thumbnail: null,
          custom_command: null
        },
        downloadState.subtitle_id,
        downloadState
      );
      return Promise.resolve();
    } catch (e) {
      console.error(`Failed to resume download: ${e}`);
      LOG.error('NEODLP', `Failed to resume download with id: ${downloadState.download_id} with error: ${e}`);
      throw e;
    }
  };

  const cancelDownload = async (downloadState: DownloadState) => {
    try {
      LOG.info('NEODLP', `Cancelling yt-dlp download with id: ${downloadState.download_id} (as per user request)`);
      if ((downloadState.download_status === 'downloading' && downloadState.process_id) || (downloadState.download_status === 'starting' && downloadState.process_id)) {
        setIsErrorExpected(true); // Set error expected to true to handle UI state
        console.log("Killing process with PID:", downloadState.process_id);
        await invoke('kill_all_process', { pid: downloadState.process_id });
      }
      downloadStateDeleter.mutate(downloadState.download_id, {
        onSuccess: (data) => {
          console.log("Download State deleted successfully:", data);
          queryClient.invalidateQueries({ queryKey: ['download-states'] });
          // Reset processing flag and trigger queue processing
          isProcessingQueueRef.current = false;

          // Process the queue after a short delay
          setTimeout(() => {
            processQueuedDownloads();
          }, 1000);
        },
        onError: (error) => {
          console.error("Failed to delete download state:", error);
          isProcessingQueueRef.current = false;
        }
      })
      return Promise.resolve();
    } catch (e) {
      console.error(`Failed to cancel download: ${e}`);
      LOG.error('NEODLP', `Failed to cancel download with id: ${downloadState.download_id} with error: ${e}`);
      throw e;
    }
  }

  const processQueuedDownloads = useCallback(async () => {
    // Prevent concurrent processing
    if (isProcessingQueueRef.current) {
      console.log("Queue processing already in progress, skipping...");
      return;
    }

    // Check if we can process more downloads
    if (!queuedDownloads?.length || ongoingDownloads?.length >= MAX_PARALLEL_DOWNLOADS) {
      return;
    }

    try {
      isProcessingQueueRef.current = true;
      console.log("Processing download queue...");

      // Get the first download in queue
      const downloadToStart = queuedDownloads[0];

      // Skip if we just processed this download to prevent loops
      if (lastProcessedDownloadIdRef.current === downloadToStart.download_id) {
        console.log("Skipping recently processed download:", downloadToStart.download_id);
        return;
      }

      // Double-check current state from global state
      const currentState = globalDownloadStates.find(
        state => state.download_id === downloadToStart.download_id
      );

      if (!currentState || currentState.download_status !== 'queued') {
        console.log("Download no longer in queued state:", downloadToStart.download_id);
        return;
      }

      console.log("Starting queued download:", downloadToStart.download_id);
      LOG.info('NEODLP', `Starting queued download with id: ${downloadToStart.download_id}`);
      lastProcessedDownloadIdRef.current = downloadToStart.download_id;

      // Update status to 'starting' first
      await downloadStatusUpdater.mutateAsync({
        download_id: downloadToStart.download_id,
        download_status: 'starting'
      });

      // Fetch latest state after status update
      await queryClient.invalidateQueries({ queryKey: ['download-states'] });

      // Start the download
      await startDownload(
        downloadToStart.url,
        downloadToStart.format_id,
        downloadToStart.queue_config ? JSON.parse(downloadToStart.queue_config) : {
          output_format: null,
          embed_metadata: null,
          embed_thumbnail: null,
          custom_command: null
        },
        downloadToStart.subtitle_id,
        downloadToStart
      );

    } catch (error) {
      console.error("Error processing download queue:", error);
      LOG.error('NEODLP', `Error processing download queue: ${error}`);
    } finally {
      // Important: reset the processing flag
      setTimeout(() => {
        isProcessingQueueRef.current = false;
        console.log("Queue processor released lock");
      }, 1000); // Small delay to prevent rapid re-processing
    }
  }, [queuedDownloads, ongoingDownloads, globalDownloadStates, queryClient]);

  // Prevent right click context menu in production
  if (!import.meta.env.DEV) {
    document.oncontextmenu = (event) => {
        event.preventDefault()
    }
  }

  // Check for App updates
  useEffect(() => {
    checkForAppUpdate().catch((error) => {
      console.error("Error checking for app update:", error);
    });
  }, []);

  // Prevent app from closing
  useEffect(() => {
    const handleCloseRequested = (event: any) => {
      event.preventDefault();
      appWindow.hide();
    };

    appWindow.onCloseRequested(handleCloseRequested);
  }, []);

  // Listen for websocket messages
  useEffect(() => {
    const unlisten = listen<WebSocketMessage>('websocket-message', (event) => {
      if(event.payload.command === 'download') {
        const handleDownload = async () => {
          appWindow.show();
          appWindow.setFocus();
          navigate('/');
          if (event.payload.url) {
            LOG.info('NEODLP', `Received download request from neodlp browser extension for URL: ${event.payload.url}`);
            const { setRequestedUrl, setAutoSubmitSearch } = useCurrentVideoMetadataStore.getState();
            setRequestedUrl(event.payload.url);
            setAutoSubmitSearch(true);
          }
        }
        handleDownload().catch((error) => {
          console.error("Error handling download:", error);
        });
      }
    });

    return () => {
      unlisten.then(f => f());
    };
  }, []);

  // useEffect(() => {
  //   const fetchConfigPath = async () => {
  //     const configPath = await invoke('get_config_file_path');
  //     console.log("Config path fetched successfully:", configPath);
  //   };

  //   fetchConfigPath().catch((error) => {
  //     console.error("Error fetching config path:", error);
  //   });
  // }, []);

  // Fetch download states from database and sync with state
  useEffect(() => {
    if (isSuccessFetchingSettings && settings) {
      console.log("Settings fetched successfully:", settings);
      if (!isObjEmpty(settings)) {
        setIsUsingDefaultSettings(false);
        Object.keys(settings).forEach((key) => {
          setSettingsKey(key, settings[key]);
        });
      }
      else {
        setIsUsingDefaultSettings(true);
      }
      setIsSettingsStatePropagated(true);
    }
  }, [settings, isSuccessFetchingSettings]);

  // Fetch KV pairs from database and sync with state
  useEffect(() => {
    if (isSuccessFetchingKvPairs && kvPairs) {
      console.log("KvPairs fetched successfully:", kvPairs);
      if (!isObjEmpty(kvPairs)) {
        Object.keys(kvPairs).forEach((key) => {
          setKvPairsKey(key, kvPairs[key]);
        });
      }
      setIsKvPairsStatePropagated(true);
    }
  }, [kvPairs, isSuccessFetchingKvPairs]);

  // Initiate/Resolve base app paths
  useEffect(() => {
    const initPaths = async () => {
      try {
        const currentArch = arch();
        const currentExeExtension = exeExtension();
        const downloadDirPath = await downloadDir();
        const tempDirPath = await tempDir();
        const resourceDirPath = await resourceDir();

        const ffmpegPath = await join(resourceDirPath, 'binaries', `ffmpeg-${currentArch}${currentExeExtension ? '.' + currentExeExtension : ''}`);
        const tempDownloadDirPath = await join(tempDirPath, config.appPkgName, 'downloads');
        const appDownloadDirPath = await join(downloadDirPath, config.appName);

        if(!await fs.exists(tempDownloadDirPath)) fs.mkdir(tempDownloadDirPath, { recursive: true }).then(() => { console.log(`Created DIR: ${tempDownloadDirPath}`) });

        setPath('ffmpegPath', ffmpegPath);
        setPath('tempDownloadDirPath', tempDownloadDirPath);
        if (DOWNLOAD_DIR) {
          setPath('downloadDirPath', DOWNLOAD_DIR);
        } else {
          if(!await fs.exists(appDownloadDirPath)) fs.mkdir(appDownloadDirPath, { recursive: true }).then(() => { console.log(`Created DIR: ${appDownloadDirPath}`) });
          setPath('downloadDirPath', appDownloadDirPath);
        }
        console.log('Paths initialized:', { ffmpegPath, tempDownloadDirPath, downloadDirPath: DOWNLOAD_DIR || appDownloadDirPath });
      } catch (e) {
        console.error('Failed to fetch paths:', e);
      }
    };
    initPaths();
  }, [DOWNLOAD_DIR, setPath]);

  // Fetch app version
  useEffect(() => {
    const fetchAppVersion = async () => {
      setIsFetchingAppVersion(true);
      try {
        const version = await getVersion();
        console.log("App version fetched successfully:", version);
        setAppVersion(version);
      } catch (e) {
        console.error('Failed to fetch app version:', e);
      } finally {
        setIsFetchingAppVersion(false);
      }
    }
    fetchAppVersion();
  }, []);

  // Fetch yt-dlp version
  useEffect(() => {
    const fetchYtDlpVersion = async () => {
      setIsFetchingYtDlpVersion(true);
      try {
        const command = Command.sidecar('binaries/yt-dlp', ['--version']);
        const output = await command.execute();
        if (output.code === 0) {
          const version = output.stdout.trim();
          console.log("yt-dlp version fetched successfully:", version);
          setYtDlpVersion(version);
        } else {
          console.error("Failed to fetch yt-dlp version:", output.stderr);
        }
      } catch (e) {
        console.error('Failed to fetch yt-dlp version:', e);
      } finally {
        setIsFetchingYtDlpVersion(false);
      }
    };
    fetchYtDlpVersion();
  }, [ytDlpVersion, setYtDlpVersion]);

  // Check for yt-dlp auto-update
  useEffect(() => {
    // Only run once when both settings and KV pairs are loaded
    if (!isSettingsStatePropagated || !isKvPairsStatePropagated) {
      console.log("Skipping yt-dlp auto-update check, waiting for configs to load...");
      return;
    }
    // Skip if we've already run the auto-update once
    if (hasRunYtDlpAutoUpdateRef.current) {
      console.log("Auto-update check already performed in this session, skipping");
      return;
    }
    hasRunYtDlpAutoUpdateRef.current = true;
    console.log("Checking yt-dlp auto-update with loaded config values:", {
      autoUpdate: YTDLP_AUTO_UPDATE,
      updateChannel: YTDLP_UPDATE_CHANNEL,
      lastCheck: ytDlpUpdateLastCheck
    });
    const currentTimestamp = Date.now()
    const YTDLP_UPDATE_INTERVAL = 86400000   // 24H;
    if (YTDLP_AUTO_UPDATE && (ytDlpUpdateLastCheck === null || currentTimestamp - ytDlpUpdateLastCheck > YTDLP_UPDATE_INTERVAL)) {
      console.log("Running auto-update for yt-dlp...");
      LOG.info('NEODLP', 'Updating yt-dlp to latest version (triggered because auto-update is enabled)');
      updateYtDlp();
    } else {
      console.log("Skipping yt-dlp auto-update, either disabled or recently updated.");
    }
  }, [isSettingsStatePropagated, isKvPairsStatePropagated]);

  // Check for MacOS auto-registration
  useEffect(() => {
    // Only run once when both settings and KV pairs are loaded
    if (!isSettingsStatePropagated || !isKvPairsStatePropagated) {
      console.log("Skipping MacOS auto registration, waiting for configs to load...");
      return;
    }
    // Skip if we've already run the macos auto-registration once
    if (isRegisteredToMacOsRef.current) {
      console.log("MacOS auto registration check already performed in this session, skipping");
      return;
    }
    isRegisteredToMacOsRef.current = true;
    console.log("Checking MacOS auto registration with loaded config values:", {
      appVersion: appVersion,
      registeredVersion: macOsRegisteredVersion
    });
    if (currentPlatform === 'macos' && (!macOsRegisteredVersion || macOsRegisteredVersion !== appVersion)) {
      console.log("Running MacOS auto registration...");
      LOG.info('NEODLP', 'Running macOS registration');
      registerToMac().then((result: { success: boolean, message: string }) => {
        if (result.success) {
          console.log("MacOS registration successful:", result.message);
          LOG.info('NEODLP', 'macOS registration successful');
        } else {
          console.error("MacOS registration failed:", result.message);
          LOG.error('NEODLP', `macOS registration failed: ${result.message}`);
        }
      }).catch((error) => {
        console.error("Error during macOS registration:", error);
        LOG.error('NEODLP', `Error during macOS registration: ${error}`);
      });
    }
  }, [isSettingsStatePropagated, isKvPairsStatePropagated]);

  useEffect(() => {
    if (isSuccessFetchingDownloadStates && downloadStates) {
      console.log("Download States fetched successfully:", downloadStates);
      setDownloadStates(downloadStates);
    }
  }, [downloadStates, isSuccessFetchingDownloadStates, setDownloadStates]);

  // Process queued downloads
  useEffect(() => {
    // Safely process the queue when dependencies change
    const timeoutId = setTimeout(() => {
      processQueuedDownloads();
    }, 500);

    // Cleanup timeout if component unmounts or dependencies change
    return () => clearTimeout(timeoutId);
  }, [processQueuedDownloads, ongoingDownloads, queuedDownloads]);

  // show a toast and pause the download when yt-dlp exits unexpectedly
  useEffect(() => {
    if (isErrored && !isErrorExpected) {
      toast.error("Download Failed", {
        description: "yt-dlp exited unexpectedly. Please try again later",
      });
      if (erroredDownloadId) {
        downloadStatusUpdater.mutate({ download_id: erroredDownloadId, download_status: 'paused' }, {
          onSuccess: (data) => {
            console.log("Download status updated successfully:", data);
            queryClient.invalidateQueries({ queryKey: ['download-states'] });
          },
          onError: (error) => {
            console.error("Failed to update download status:", error);
          }
        })
        setErroredDownloadId(null);
      }
      setIsErrored(false);
      setIsErrorExpected(false);
    }
  }, [isErrored, isErrorExpected, erroredDownloadId, setIsErrored, setIsErrorExpected, setErroredDownloadId]);

  // auto reset error states after 3 seconds of expecting an error
  useEffect(() => {
    if (isErrorExpected) {
      const timeoutId = setTimeout(() => {
        setIsErrored(false);
        setIsErrorExpected(false);
        setErroredDownloadId(null);
      }, 3000);
      return () => clearTimeout(timeoutId);
    }
  }, [isErrorExpected, setIsErrorExpected]);

  return (
    <AppContext.Provider value={{ fetchVideoMetadata, startDownload, pauseDownload, resumeDownload, cancelDownload }}>
      <ThemeProvider defaultTheme={APP_THEME || "system"} storageKey="vite-ui-theme">
          <TooltipProvider delayDuration={1000}>
            {children}
            <Sonner closeButton />
          </TooltipProvider>
      </ThemeProvider>
    </AppContext.Provider>
  );
}
