/**
 * TanStack Query hook for moderation queue data fetching
 * 
 * Wraps the existing fetchSubmissions query builder with React Query
 * to provide automatic caching, deduplication, and background refetching.
 */

import { useQuery, useQueryClient } from '@tanstack/react-query';
import { fetchSubmissions, type QueryConfig } from '@/lib/moderation/queries';
import { supabase } from '@/integrations/supabase/client';
import { logger } from '@/lib/logger';
import { getErrorMessage } from '@/lib/errorHandler';
import { MODERATION_CONSTANTS } from '@/lib/moderation/constants';
import { validateModerationItems } from '@/lib/moderation/validation';
import type { 
  ModerationItem, 
  EntityFilter, 
  StatusFilter, 
  QueueTab, 
  SortField, 
  SortDirection 
} from '@/types/moderation';

/**
 * Get specific, actionable error message based on error type
 */
function getSpecificErrorMessage(error: unknown): string {
  // Offline detection
  if (!navigator.onLine) {
    return 'You appear to be offline. Check your internet connection and try again.';
  }
  
  // Timeout
  if (error instanceof Error && error.name === 'AbortError') {
    return 'Request timed out. The server is taking too long to respond. Please try again.';
  }
  
  // Check for Supabase-specific errors
  if (typeof error === 'object' && error !== null) {
    const err = error as any;
    
    // 500 errors
    if (err.status === 500 || err.code === '500') {
      return 'Server error occurred. Our team has been notified. Please try again in a few minutes.';
    }
    
    // 429 Rate limiting
    if (err.status === 429 || err.message?.includes('rate limit')) {
      return 'Too many requests. Please wait a moment before trying again.';
    }
    
    // Authentication errors
    if (err.status === 401 || err.message?.includes('JWT')) {
      return 'Your session has expired. Please refresh the page and sign in again.';
    }
    
    // Permission errors
    if (err.status === 403 || err.message?.includes('permission')) {
      return 'You do not have permission to access the moderation queue.';
    }
  }
  
  // Fallback
  return getErrorMessage(error) || 'Failed to load moderation queue. Please try again.';
}

/**
 * Configuration for queue query
 */
export interface UseQueueQueryConfig {
  /** User making the query */
  userId: string | undefined;
  
  /** Whether user is admin */
  isAdmin: boolean;
  
  /** Whether user is superuser */
  isSuperuser: boolean;
  
  /** Entity filter */
  entityFilter: EntityFilter;
  
  /** Status filter */
  statusFilter: StatusFilter;
  
  /** Active tab */
  tab: QueueTab;
  
  /** Current page */
  currentPage: number;
  
  /** Page size */
  pageSize: number;
  
  /** Sort configuration */
  sortConfig: {
    field: SortField;
    direction: SortDirection;
  };
  
  /** Whether query is enabled (defaults to true) */
  enabled?: boolean;
}

/**
 * Return type for useQueueQuery
 */
export interface UseQueueQueryReturn {
  /** Queue items */
  items: ModerationItem[];
  
  /** Total count of items matching filters */
  totalCount: number;
  
  /** Initial loading state (no data yet) */
  isLoading: boolean;
  
  /** Background refresh in progress (has data already) */
  isRefreshing: boolean;
  
  /** Any error that occurred */
  error: Error | null;
  
  /** Manually trigger a refetch */
  refetch: () => Promise<any>;
  
  /** Invalidate this query (triggers background refetch) */
  invalidate: () => Promise<void>;
}

/**
 * Hook to fetch moderation queue data using TanStack Query
 */
export function useQueueQuery(config: UseQueueQueryConfig): UseQueueQueryReturn {
  const queryClient = useQueryClient();
  
  // Build query config for fetchSubmissions
  const queryConfig: QueryConfig = {
    userId: config.userId || '',
    isAdmin: config.isAdmin,
    isSuperuser: config.isSuperuser,
    entityFilter: config.entityFilter,
    statusFilter: config.statusFilter,
    tab: config.tab,
    currentPage: config.currentPage,
    pageSize: config.pageSize,
    sortConfig: config.sortConfig,
  };
  
  // Create stable query key (TanStack Query uses this for caching/deduplication)
  // Include user context to ensure proper cache isolation per user/role
  const queryKey = [
    'moderation-queue',
    config.userId,
    config.isAdmin,
    config.isSuperuser,
    config.entityFilter,
    config.statusFilter,
    config.tab,
    config.currentPage,
    config.pageSize,
    config.sortConfig.field,
    config.sortConfig.direction,
  ];
  
  // Execute query
  const query = useQuery({
    queryKey,
    queryFn: async () => {
      logger.log('🔍 [TanStack Query] Fetching queue data:', queryKey);
      
      // Create timeout controller (30s timeout)
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 30000);
      
      try {
        const result = await fetchSubmissions(supabase, queryConfig);
        clearTimeout(timeoutId);
        
        if (result.error) {
          const specificMessage = getSpecificErrorMessage(result.error);
          logger.error('❌ [TanStack Query] Error:', { error: specificMessage });
          throw new Error(specificMessage);
        }
        
        // Validate data shape before returning
        const validation = validateModerationItems(result.submissions);
        if (!validation.success) {
          logger.error('❌ Invalid data shape', { error: validation.error });
          throw new Error(validation.error || 'Invalid data format');
        }
        
        logger.log('✅ [TanStack Query] Fetched', validation.data!.length, 'items');
        return { ...result, submissions: validation.data! };
      } catch (error) {
        clearTimeout(timeoutId);
        throw error;
      }
    },
    enabled: config.enabled !== false && !!config.userId,
    staleTime: MODERATION_CONSTANTS.QUERY_STALE_TIME,
    gcTime: MODERATION_CONSTANTS.QUERY_GC_TIME,
    retry: MODERATION_CONSTANTS.QUERY_RETRY_COUNT,
    retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
    networkMode: 'offlineFirst', // Handle offline gracefully
    meta: {
      errorMessage: 'Failed to load moderation queue',
    },
  });
  
  // Invalidate helper
  const invalidate = async () => {
    await queryClient.invalidateQueries({ queryKey: ['moderation-queue'] });
  };
  
  return {
    items: query.data?.submissions || [],
    totalCount: query.data?.totalCount || 0,
    isLoading: query.isLoading,
    isRefreshing: query.isFetching && !query.isLoading,
    error: query.error as Error | null,
    refetch: query.refetch,
    invalidate,
  };
}
