import { useState, useCallback, useRef, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { useAuth } from "@/hooks/useAuth";
import { logger } from "@/lib/logger";
import { getErrorMessage } from "@/lib/errorHandler";
import { invokeWithTracking } from "@/lib/edgeFunctionTracking";
import { MODERATION_CONSTANTS } from "@/lib/moderation/constants";
import { useQueryClient } from '@tanstack/react-query';
import type { User } from "@supabase/supabase-js";
import {
  useEntityCache,
  useProfileCache,
  useModerationFilters,
  usePagination,
  useRealtimeSubscriptions,
  useQueueQuery,
} from "./index";
import { useModerationQueue } from "@/hooks/useModerationQueue";
import { useModerationActions } from "./useModerationActions";

import type { ModerationItem, EntityFilter, StatusFilter, LoadingState } from "@/types/moderation";

interface ModerationStats {
  pendingSubmissions: number;
  openReports: number;
  flaggedContent: number;
}

/**
 * Configuration for useModerationQueueManager
 */
export interface ModerationQueueManagerConfig {
  user: User | null;
  isAdmin: boolean;
  isSuperuser: boolean;
  toast: ReturnType<typeof useToast>["toast"];
  optimisticallyUpdateStats?: (delta: Partial<ModerationStats>) => void;
  settings: {
    refreshMode: "auto" | "manual";
    pollInterval: number;
    refreshStrategy: "notify" | "merge" | "replace";
    preserveInteraction: boolean;
    useRealtimeQueue: boolean;
  };
}

/**
 * Return type for useModerationQueueManager
 */
export interface ModerationQueueManager {
  // State
  items: ModerationItem[];
  loadingState: LoadingState;
  actionLoading: string | null;

  // Sub-hooks (exposed for granular control)
  filters: ReturnType<typeof useModerationFilters>;
  pagination: ReturnType<typeof usePagination>;
  queue: ReturnType<typeof useModerationQueue>;

  // Realtime
  newItemsCount: number;
  pendingNewItems: ModerationItem[];
  showNewItems: () => void;

  // Interaction tracking
  interactingWith: Set<string>;
  markInteracting: (id: string, interacting: boolean) => void;

  // Actions
  refresh: () => void;
  performAction: (item: ModerationItem, action: "approved" | "rejected", moderatorNotes?: string) => Promise<void>;
  deleteSubmission: (item: ModerationItem) => Promise<void>;
  resetToPending: (item: ModerationItem) => Promise<void>;
  retryFailedItems: (item: ModerationItem) => Promise<void>;

  // Caches (for QueueItem enrichment)
  entityCache: ReturnType<typeof useEntityCache>;
  profileCache: ReturnType<typeof useProfileCache>;
}

/**
 * Orchestrator hook for moderation queue management
 * Consolidates all queue-related logic into a single hook
 */
export function useModerationQueueManager(config: ModerationQueueManagerConfig): ModerationQueueManager {
  logger.log('🚀 [QUEUE MANAGER] Hook mounting/rendering', { 
    hasUser: !!config.user, 
    isAdmin: config.isAdmin, 
    timestamp: new Date().toISOString() 
  });
  
  const { user, isAdmin, isSuperuser, toast, optimisticallyUpdateStats, settings } = config;
  const queryClient = useQueryClient();
  const { aal } = useAuth();

  // Debug AAL status
  useEffect(() => {
    logger.log('🔐 [QUEUE MANAGER] AAL Status:', { 
      aal, 
      isNull: aal === null,
      isAal1: aal === 'aal1',
      isAal2: aal === 'aal2',
      timestamp: new Date().toISOString()
    });
  }, [aal]);

  // Initialize sub-hooks
  const filters = useModerationFilters({
    initialEntityFilter: "all",
    initialStatusFilter: "pending",
    initialTab: "mainQueue",
    debounceDelay: 300,
    persist: true,
    storageKey: "moderationQueue_filters",
  });

  // Memoize filters object for realtime subscriptions to prevent reconnections
  const realtimeFilters = useMemo(() => ({
    entityFilter: filters.debouncedEntityFilter,
    statusFilter: filters.debouncedStatusFilter,
  }), [filters.debouncedEntityFilter, filters.debouncedStatusFilter]);

  const pagination = usePagination({
    initialPage: 1,
    initialPageSize: 25,
    persist: false,
    onPageChange: (page) => {
      if (page > 1) {
        setLoadingState("loading");
      }
    },
    onPageSizeChange: () => {
      setLoadingState("loading");
    },
  });

  const queue = useModerationQueue({
    onLockStateChange: () => {
      logger.log('🔄 Lock state changed, invalidating queue cache');
      queueQuery.invalidate();
      // Force immediate re-render by triggering a loading cycle
      setLoadingState(prev => prev === "loading" ? "ready" : prev);
    }
  });
  const entityCache = useEntityCache();
  const profileCache = useProfileCache();

  // Core state
  const [items, setItems] = useState<ModerationItem[]>([]);
  const [loadingState, setLoadingState] = useState<LoadingState>("initial");
  const [actionLoading, setActionLoading] = useState<string | null>(null);
  const [interactingWith, setInteractingWith] = useState<Set<string>>(new Set());
  const [pendingNewItems, setPendingNewItems] = useState<ModerationItem[]>([]);
  const [newItemsCount, setNewItemsCount] = useState(0);

  // Refs for tracking
  const recentlyRemovedRef = useRef<Set<string>>(new Set());
  const initialFetchCompleteRef = useRef(false);
  const isMountingRef = useRef(true);

  // Store settings, filters, and pagination in refs to stabilize fetchItems
  const settingsRef = useRef(settings);
  const filtersRef = useRef(filters);
  const sortRef = useRef(filters.debouncedSortConfig);
  const paginationRef = useRef(pagination);

  // Sync refs with state
  useEffect(() => {
    settingsRef.current = settings;
  }, [settings]);

  useEffect(() => {
    filtersRef.current = filters;
  }, [filters]);

  useEffect(() => {
    sortRef.current = filters.debouncedSortConfig;
  }, [filters.debouncedSortConfig]);

  useEffect(() => {
    paginationRef.current = pagination;
  }, [pagination]);

  /**
   * Replace manual fetching with TanStack Query
   */
  const queueQuery = useQueueQuery({
    userId: user?.id,
    isAdmin,
    isSuperuser,
    entityFilter: filtersRef.current.debouncedEntityFilter,
    statusFilter: filtersRef.current.debouncedStatusFilter,
    tab: filtersRef.current.activeTab,
    currentPage: paginationRef.current.currentPage,
    pageSize: paginationRef.current.pageSize,
    sortConfig: sortRef.current,
    enabled: !!user,
  });

  // Update items when query data changes
  useEffect(() => {
    if (queueQuery.items) {
      setItems(queueQuery.items);
      logger.log('✅ Queue items updated from TanStack Query:', queueQuery.items.length);
    }
  }, [queueQuery.items]);

  // Update loading state based on query status
  useEffect(() => {
    if (queueQuery.isLoading) {
      setLoadingState('loading');
    } else if (queueQuery.isRefreshing) {
      setLoadingState('refreshing');
    } else {
      setLoadingState('ready');
    }
  }, [queueQuery.isLoading, queueQuery.isRefreshing]);

  // Show error toast when query fails
  useEffect(() => {
    if (queueQuery.error) {
      logger.error('❌ Queue query error:', { error: getErrorMessage(queueQuery.error) });
      toast({
        variant: 'destructive',
        title: 'Failed to Load Queue',
        description: queueQuery.error.message || 'An error occurred while fetching the moderation queue.',
      });
    }
  }, [queueQuery.error, toast]);

  // Update total count for pagination
  useEffect(() => {
    paginationRef.current.setTotalCount(queueQuery.totalCount);
  }, [queueQuery.totalCount]);

  // Mark initial fetch as complete
  useEffect(() => {
    if (!queueQuery.isLoading && !initialFetchCompleteRef.current) {
      initialFetchCompleteRef.current = true;
      logger.log('✅ Initial queue fetch complete');
    }
  }, [queueQuery.isLoading]);

  /**
   * Manual refresh function
   */
  const refresh = useCallback(async () => {
    logger.log('🔄 Manual refresh triggered');
    await queueQuery.refetch();
  }, [queueQuery]);

  /**
   * Show pending new items by invalidating query
   */
  const showNewItems = useCallback(async () => {
    logger.log('✅ Showing new items via query invalidation');
    await queueQuery.invalidate();
    setPendingNewItems([]);
    setNewItemsCount(0);
  }, [queueQuery]);

  /**
   * Mark an item as being interacted with (prevents realtime updates)
   */
  const markInteracting = useCallback((id: string, interacting: boolean) => {
    setInteractingWith((prev) => {
      const next = new Set(prev);
      if (interacting) {
        next.add(id);
      } else {
        next.delete(id);
      }
      return next;
    });
  }, []);

  /**
   * Use validated action handler from useModerationActions
   */
  const moderationActions = useModerationActions({
    user,
    onActionStart: setActionLoading,
    onActionComplete: () => {
      setActionLoading(null);
      refresh();
      queue.refreshStats();
    },
    currentLockSubmissionId: queue.currentLock?.submissionId,
  });

  /**
   * Perform moderation action (approve/reject) - delegates to validated handler
   */
  const performAction = useCallback(
    async (item: ModerationItem, action: "approved" | "rejected", moderatorNotes?: string) => {
      // Release lock if held
      if (queue.currentLock?.submissionId === item.id) {
        await queue.releaseLock(item.id, true);
      }
      
      // Use validated action handler
      await moderationActions.performAction(item, action, moderatorNotes);
    },
    [moderationActions, queue]
  );


  /**
   * Delete a submission permanently
   */
  const deleteSubmission = useCallback(
    async (item: ModerationItem) => {
      if (item.type !== "content_submission") return;
      if (actionLoading === item.id) return;

      setActionLoading(item.id);
      setItems((prev) => prev.filter((i) => i.id !== item.id));

      try {
        const { error } = await supabase.from("content_submissions").delete().eq("id", item.id);

        if (error) throw error;

      toast({
        title: "Submission deleted",
        description: "The submission has been permanently deleted",
      });
      
      // Refresh stats to update counts
      queue.refreshStats();
      } catch (error: unknown) {
        const errorMsg = getErrorMessage(error);
        logger.error("Error deleting submission:", { error: errorMsg, itemId: item.id });

        setItems((prev) => {
          if (prev.some((i) => i.id === item.id)) return prev;
          return [...prev, item];
        });

        toast({
          title: "Error",
          description: "Failed to delete submission",
          variant: "destructive",
        });
      } finally {
        setActionLoading(null);
      }
    },
    [actionLoading, toast],
  );

  /**
   * Reset submission to pending status
   */
  const resetToPending = useCallback(
    async (item: ModerationItem) => {
      setActionLoading(item.id);

      try {
        const { resetRejectedItemsToPending } = await import("@/lib/submissionItemsService");
        await resetRejectedItemsToPending(item.id);

        toast({
          title: "Reset Complete",
          description: "Submission and all items have been reset to pending status",
        });
        
        // Refresh stats to update counts
        queue.refreshStats();

        setItems((prev) => prev.filter((i) => i.id !== item.id));
      } catch (error: unknown) {
        const errorMsg = getErrorMessage(error);
        logger.error("Error resetting submission:", { error: errorMsg, itemId: item.id });
        toast({
          title: "Reset Failed",
          description: errorMsg,
          variant: "destructive",
        });
      } finally {
        setActionLoading(null);
      }
    },
    [toast],
  );

  /**
   * Retry failed items in a submission
   */
  const retryFailedItems = useCallback(
    async (item: ModerationItem) => {
      setActionLoading(item.id);

      const shouldRemove =
        filters.statusFilter === "pending" ||
        filters.statusFilter === "flagged" ||
        filters.statusFilter === "partially_approved";

      if (shouldRemove) {
        requestAnimationFrame(() => {
          setItems((prev) => prev.filter((i) => i.id !== item.id));
          recentlyRemovedRef.current.add(item.id);
          setTimeout(() => recentlyRemovedRef.current.delete(item.id), 10000);
        });
      }

      try {
        const { data: failedItems } = await supabase
          .from("submission_items")
          .select("id")
          .eq("submission_id", item.id)
          .eq("status", "rejected");

        if (!failedItems || failedItems.length === 0) {
          toast({
            title: "No Failed Items",
            description: "All items have been processed successfully",
          });
          return;
        }

        const { data, error, requestId } = await invokeWithTracking(
          "process-selective-approval",
          {
            itemIds: failedItems.map((i) => i.id),
            submissionId: item.id,
          },
          user?.id
        );

        if (error) throw error;

        toast({
          title: "Retry Complete",
          description: `Processed ${failedItems.length} failed item(s)${requestId ? ` (Request: ${requestId.substring(0, 8)})` : ""}`,
        });
        
        // Refresh stats to update counts
        queue.refreshStats();
      } catch (error: unknown) {
        const errorMsg = getErrorMessage(error);
        logger.error("Error retrying failed items:", { error: errorMsg, itemId: item.id });
        toast({
          title: "Retry Failed",
          description: errorMsg,
          variant: "destructive",
        });
      } finally {
        setActionLoading(null);
      }
    },
    [filters.statusFilter, toast],
  );

  // Extract stable callbacks for dependencies
  const invalidateQuery = useCallback(() => {
    queueQuery.invalidate();
  }, [queueQuery.invalidate]);

  const resetPagination = useCallback(() => {
    pagination.reset();
  }, [pagination.reset]);

  // Mark initial fetch as complete when query loads
  useEffect(() => {
    if (!queueQuery.isLoading && !initialFetchCompleteRef.current) {
      initialFetchCompleteRef.current = true;
      isMountingRef.current = false;
      logger.log('✅ Initial queue fetch complete');
    }
  }, [queueQuery.isLoading]);

  // Invalidate query when filters or sort changes (OPTIMIZED)
  useEffect(() => {
    if (
      !user ||
      !initialFetchCompleteRef.current ||
      isMountingRef.current
    ) return;

    logger.log('🔄 Filters/sort changed, invalidating query');
    resetPagination();
    invalidateQuery();
  }, [
    filters.debouncedEntityFilter,
    filters.debouncedStatusFilter,
    filters.debouncedSortConfig.field,
    filters.debouncedSortConfig.direction,
    user,
    invalidateQuery,
    resetPagination
  ]);

  // Polling effect (when realtime disabled) - MUTUALLY EXCLUSIVE
  useEffect(() => {
    const shouldPoll = settings.refreshMode === 'auto' 
      && !settings.useRealtimeQueue 
      && loadingState !== 'initial'
      && !!user;
    
    if (!shouldPoll) {
      return;
    }

    logger.log("⚠️ Polling ENABLED - interval:", settings.pollInterval);
    const interval = setInterval(() => {
      logger.log("🔄 Polling refresh triggered");
      queueQuery.refetch();
    }, settings.pollInterval);

    return () => {
      clearInterval(interval);
      logger.log("🛑 Polling stopped");
    };
  }, [user, settings.refreshMode, settings.pollInterval, loadingState, settings.useRealtimeQueue, queueQuery.refetch]);

  // Initialize realtime subscriptions
  useRealtimeSubscriptions({
    enabled: settings.useRealtimeQueue && !!user,
    filters: realtimeFilters,
    onNewItem: (item: ModerationItem) => {
      if (recentlyRemovedRef.current.has(item.id)) return;

      setPendingNewItems((prev) => {
        if (prev.some((p) => p.id === item.id)) return prev;
        return [...prev, item];
      });
      setNewItemsCount((prev) => prev + 1);

      toast({
        title: "🆕 New Submission",
        description: `${item.submission_type} - ${item.entity_name}`,
      });
    },
    onUpdateItem: (item: ModerationItem, shouldRemove: boolean) => {
      if (recentlyRemovedRef.current.has(item.id)) return;
      if (interactingWith.has(item.id)) return;

      // Only track removals for optimistic update protection
      if (shouldRemove && !recentlyRemovedRef.current.has(item.id)) {
        recentlyRemovedRef.current.add(item.id);
        setTimeout(() => recentlyRemovedRef.current.delete(item.id), MODERATION_CONSTANTS.REALTIME_OPTIMISTIC_REMOVAL_TIMEOUT);
      }
      // TanStack Query handles actual state updates via invalidation
    },
    onItemRemoved: (itemId: string) => {
      // Track for optimistic update protection
      recentlyRemovedRef.current.add(itemId);
      setTimeout(() => recentlyRemovedRef.current.delete(itemId), MODERATION_CONSTANTS.REALTIME_OPTIMISTIC_REMOVAL_TIMEOUT);
      // TanStack Query handles removal via invalidation
    },
    entityCache,
    profileCache,
      recentlyRemovedIds: recentlyRemovedRef.current,
      interactingWithIds: interactingWith,
    });

  return {
    items,
    loadingState,
    actionLoading,
    filters,
    pagination,
    queue,
    newItemsCount,
    pendingNewItems,
    showNewItems,
    interactingWith,
    markInteracting,
    refresh,
    performAction,
    deleteSubmission,
    resetToPending,
    retryFailedItems,
    entityCache,
    profileCache,
  };
}
