/**
 * @ai-summary Authentication gate to ensure API requests wait for auth initialization
 * @ai-context Prevents race conditions between IndexedDB init and API calls
 */

import { useState, useEffect } from 'react';

// Global authentication readiness state
let authInitialized = false;
let authInitPromise: Promise<void> | null = null;
let resolveAuthInit: (() => void) | null = null;

// Subscription-based state change notification (replaces polling)
type AuthStateListener = (initialized: boolean) => void;
const listeners: Set<AuthStateListener> = new Set();

const notifyListeners = (initialized: boolean) => {
  listeners.forEach(listener => listener(initialized));
};

export const subscribeToAuthState = (listener: AuthStateListener): (() => void) => {
  listeners.add(listener);
  // Immediately notify of current state
  listener(authInitialized);
  return () => listeners.delete(listener);
};

// Debug logging
console.log('[Auth Gate] Module loaded, authInitialized:', authInitialized);

// Request queue to hold requests until auth is ready
interface QueuedRequest {
  resolve: (value: any) => void;
  reject: (error: any) => void;
  requestFn: () => Promise<any>;
}

let requestQueue: QueuedRequest[] = [];
let isProcessingQueue = false;

export const waitForAuthInit = (): Promise<void> => {
  if (authInitialized) {
    return Promise.resolve();
  }

  if (!authInitPromise) {
    authInitPromise = new Promise((resolve) => {
      resolveAuthInit = resolve;
    });
  }

  return authInitPromise;
};

export const setAuthInitialized = (initialized: boolean) => {
  console.log('[DEBUG] setAuthInitialized called with:', initialized, '(was:', authInitialized, ')');
  authInitialized = initialized;

  // Notify all subscribers of state change
  notifyListeners(initialized);

  if (initialized) {
    console.log('[DEBUG Auth Gate] Authentication fully initialized');

    // Resolve the auth promise
    if (resolveAuthInit) {
      resolveAuthInit();
      resolveAuthInit = null;
    }

    // Process any queued requests
    processRequestQueue();
  } else {
    // Reset state when auth becomes unavailable
    authInitPromise = null;
    resolveAuthInit = null;
    requestQueue = [];
  }
};

export const isAuthInitialized = () => authInitialized;

// Queue a request until auth is ready
export const queueRequest = <T>(requestFn: () => Promise<T>): Promise<T> => {
  if (authInitialized) {
    return requestFn();
  }

  return new Promise((resolve, reject) => {
    requestQueue.push({
      resolve,
      reject,
      requestFn
    });

    console.log(`[Auth Gate] Queued request, ${requestQueue.length} total in queue`);
  });
};

// Process all queued requests
const processRequestQueue = async () => {
  if (isProcessingQueue || requestQueue.length === 0) {
    return;
  }

  isProcessingQueue = true;
  console.log(`[Auth Gate] Processing ${requestQueue.length} queued requests`);

  const queueToProcess = [...requestQueue];
  requestQueue = [];

  for (const { resolve, reject, requestFn } of queueToProcess) {
    try {
      const result = await requestFn();
      resolve(result);
    } catch (error) {
      reject(error);
    }
  }

  isProcessingQueue = false;
  console.log('[Auth Gate] Finished processing queued requests');
};

/**
 * React hook to track auth initialization state
 * Returns true once auth is fully initialized with token
 * Uses subscription-based notification for immediate state changes
 */
export const useIsAuthInitialized = () => {
  const [initialized, setInitialized] = useState(isAuthInitialized());

  useEffect(() => {
    // Subscribe to auth state changes
    const unsubscribe = subscribeToAuthState((isInit) => {
      if (isInit) {
        console.log('[useIsAuthInitialized] Auth initialized via subscription');
        setInitialized(true);
      }
    });

    return unsubscribe;
  }, []);

  return initialized;
};