import { useCallback, useEffect, useRef } from 'react';
import { useAuth } from '@/context/AuthContext';
import { useEnv } from '@/context/EnvContext';
import { useLibraryStore } from '@/store/libraryStore';
import { useSettingsStore } from '@/store/settingsStore';
import { isReadestCloudStorageActive } from '@/services/sync/cloudSyncProvider';
import { useTranslation } from '@/hooks/useTranslation';
import { syncSubscribedCatalogs } from '@/services/opds';
import { AUTO_CHECK_INTERVAL_MS } from '@/services/opds/types';
import { transferManager } from '@/services/transferManager';
import { eventDispatcher } from '@/utils/event';

export function useOPDSSubscriptions() {
  const _ = useTranslation();
  const { appService } = useEnv();
  const { user } = useAuth();
  const { libraryLoaded } = useLibraryStore();
  const isSyncingRef = useRef(false);

  const checkOPDSSubscriptions = useCallback(
    async (verbose = false) => {
      if (!appService || !libraryLoaded) return;
      if (isSyncingRef.current) return;

      const { settings } = useSettingsStore.getState();
      const catalogs = settings.opdsCatalogs ?? [];
      const hasAutoDownload = catalogs.some((c) => c.autoDownload && !c.disabled);
      if (!hasAutoDownload) return;

      console.log(`[OPDS] checking subscriptions`);
      try {
        isSyncingRef.current = true;
        const librarySnapshot = [...useLibraryStore.getState().library];
        const { newBooks, totalNewBooks, errors } = await syncSubscribedCatalogs(
          catalogs,
          appService,
          librarySnapshot,
        );

        if (totalNewBooks > 0) {
          const currentLibrary = useLibraryStore.getState().library;
          const existingHashes = new Set(currentLibrary.map((b) => b.hash));
          const uniqueNewBooks = newBooks.filter((b) => !existingHashes.has(b.hash));
          if (uniqueNewBooks.length > 0) {
            const merged = [...uniqueNewBooks, ...currentLibrary];
            useLibraryStore.getState().setLibrary(merged);
            appService.saveLibraryBooks(merged);
          }

          // Mirror the manual OPDS download path: queue cloud upload for each
          // newly imported book when the user is logged in and has the global
          // autoUpload setting on. Delay so the transfer manager has a chance
          // to finish initializing if this fires right after libraryLoaded.
          const { settings: currentSettings } = useSettingsStore.getState();
          if (
            user &&
            currentSettings.autoUpload &&
            isReadestCloudStorageActive(currentSettings) &&
            uniqueNewBooks.length > 0
          ) {
            const booksToUpload = uniqueNewBooks.filter((b) => !b.uploadedAt);
            if (booksToUpload.length > 0) {
              setTimeout(() => {
                for (const book of booksToUpload) {
                  transferManager.queueUpload(book);
                }
              }, 3000);
            }
          }
        }

        if (verbose && totalNewBooks > 0) {
          eventDispatcher.dispatch('toast', {
            type: 'info',
            message: _('{{count}} new item(s) downloaded from OPDS', { count: totalNewBooks }),
          });
        }
        if (verbose && errors.length > 0) {
          eventDispatcher.dispatch('toast', {
            type: 'error',
            timeout: 4000,
            message: _('Failed to sync {{count}} OPDS catalog(s)', { count: errors.length }),
          });
        }
      } catch (error) {
        console.error('OPDS subscription sync error:', error);
      } finally {
        isSyncingRef.current = false;
        // CatalogManager listens for this to refresh the per-catalog status
        // (last-checked time, failed-entries count) without polling.
        eventDispatcher.dispatch('opds-sync-complete');
      }
    },
    [_, appService, libraryLoaded, user],
  );

  // Auto-trigger on startup after library is loaded
  useEffect(() => {
    if (!libraryLoaded) return;
    checkOPDSSubscriptions();
  }, [libraryLoaded, checkOPDSSubscriptions]);

  // Listen for explicit re-check requests (e.g. user enables auto-download
  // on a catalog and we want to sync immediately rather than wait for the
  // next app launch).
  useEffect(() => {
    const handler = () => checkOPDSSubscriptions(true);
    eventDispatcher.on('check-opds-subscriptions', handler);
    return () => eventDispatcher.off('check-opds-subscriptions', handler);
  }, [checkOPDSSubscriptions]);

  // Periodic background check. Silent (no toasts) so it doesn't surprise the
  // user with notifications every 5 minutes; new books just appear in the
  // library when they finish downloading. The function is a no-op when no
  // catalogs have autoDownload enabled, so the timer is cheap.
  useEffect(() => {
    if (!libraryLoaded) return;
    const intervalId = setInterval(() => {
      checkOPDSSubscriptions(false);
    }, AUTO_CHECK_INTERVAL_MS);
    return () => clearInterval(intervalId);
  }, [libraryLoaded, checkOPDSSubscriptions]);

  return { checkOPDSSubscriptions };
}
