/**
 * Pagination Hook
 * 
 * Manages pagination state and actions for the moderation queue.
 */

import { useState, useCallback, useEffect, useMemo } from 'react';
import { MODERATION_CONSTANTS } from '@/lib/moderation/constants';
import * as storage from '@/lib/localStorage';

export interface PaginationConfig {
  /** Initial page number (1-indexed) */
  initialPage?: number;
  
  /** Initial page size */
  initialPageSize?: number;
  
  /** Whether to persist pagination state */
  persist?: boolean;
  
  /** localStorage key for persistence */
  storageKey?: string;
  
  /** Callback when page changes */
  onPageChange?: (page: number) => void;
  
  /** Callback when page size changes */
  onPageSizeChange?: (pageSize: number) => void;
}

export interface PaginationState {
  /** Current page (1-indexed) */
  currentPage: number;
  
  /** Items per page */
  pageSize: number;
  
  /** Total number of items */
  totalCount: number;
  
  /** Total number of pages */
  totalPages: number;
  
  /** Start index for current page (0-indexed) */
  startIndex: number;
  
  /** End index for current page (0-indexed) */
  endIndex: number;
  
  /** Whether there is a previous page */
  hasPrevPage: boolean;
  
  /** Whether there is a next page */
  hasNextPage: boolean;
  
  /** Set current page */
  setCurrentPage: (page: number) => void;
  
  /** Set page size */
  setPageSize: (size: number) => void;
  
  /** Set total count */
  setTotalCount: (count: number) => void;
  
  /** Go to next page */
  nextPage: () => void;
  
  /** Go to previous page */
  prevPage: () => void;
  
  /** Go to first page */
  firstPage: () => void;
  
  /** Go to last page */
  lastPage: () => void;
  
  /** Reset pagination */
  reset: () => void;
  
  /** Get page range for display */
  getPageRange: (maxPages?: number) => number[];
}

/**
 * Hook for managing pagination state
 * 
 * @param config - Configuration options
 * @returns Pagination state and actions
 * 
 * @example
 * ```tsx
 * const pagination = usePagination({
 *   initialPageSize: 25,
 *   persist: true,
 *   onPageChange: (page) => fetchData(page)
 * });
 * 
 * // Set total count from API
 * pagination.setTotalCount(response.count);
 * 
 * // Use in query
 * const { startIndex, endIndex } = pagination;
 * query.range(startIndex, endIndex);
 * ```
 */
export function usePagination(config: PaginationConfig = {}): PaginationState {
  const {
    initialPage = 1,
    initialPageSize = MODERATION_CONSTANTS.DEFAULT_PAGE_SIZE,
    persist = false,
    storageKey = 'pagination_state',
    onPageChange,
    onPageSizeChange,
  } = config;

  // Load persisted state
  const loadPersistedState = useCallback(() => {
    if (!persist) return null;
    
    try {
      const saved = localStorage.getItem(storageKey);
      if (saved) {
        return JSON.parse(saved);
      }
    } catch (error: unknown) {
      console.error('Failed to load pagination state:', error);
    }
    
    return null;
  }, [persist, storageKey]);

  const persisted = loadPersistedState();

  // State
  const [currentPage, setCurrentPageState] = useState<number>(
    persisted?.currentPage || initialPage
  );
  const [pageSize, setPageSizeState] = useState<number>(
    persisted?.pageSize || initialPageSize
  );
  const [totalCount, setTotalCount] = useState<number>(0);

  // Computed values
  const totalPages = useMemo(() => Math.ceil(totalCount / pageSize), [totalCount, pageSize]);
  const startIndex = useMemo(() => (currentPage - 1) * pageSize, [currentPage, pageSize]);
  const endIndex = useMemo(() => startIndex + pageSize - 1, [startIndex, pageSize]);
  const hasPrevPage = currentPage > 1;
  const hasNextPage = currentPage < totalPages;

  // Persist state
  useEffect(() => {
    if (persist) {
      storage.setJSON(storageKey, {
        currentPage,
        pageSize,
      });
    }
  }, [currentPage, pageSize, persist, storageKey]);

  // Set current page with bounds checking
  const setCurrentPage = useCallback(
    (page: number) => {
      const boundedPage = Math.max(1, Math.min(page, totalPages || 1));
      setCurrentPageState(boundedPage);
      onPageChange?.(boundedPage);
    },
    [totalPages, onPageChange]
  );

  // Set page size and reset to first page
  const setPageSize = useCallback(
    (size: number) => {
      setPageSizeState(size);
      setCurrentPageState(1);
      onPageSizeChange?.(size);
    },
    [onPageSizeChange]
  );

  // Navigation actions
  const nextPage = useCallback(() => {
    if (hasNextPage) {
      setCurrentPage(currentPage + 1);
    }
  }, [currentPage, hasNextPage, setCurrentPage]);

  const prevPage = useCallback(() => {
    if (hasPrevPage) {
      setCurrentPage(currentPage - 1);
    }
  }, [currentPage, hasPrevPage, setCurrentPage]);

  const firstPage = useCallback(() => {
    setCurrentPage(1);
  }, [setCurrentPage]);

  const lastPage = useCallback(() => {
    setCurrentPage(totalPages);
  }, [totalPages, setCurrentPage]);

  // Reset pagination
  const reset = useCallback(() => {
    setCurrentPageState(initialPage);
    setPageSizeState(initialPageSize);
    setTotalCount(0);
  }, [initialPage, initialPageSize]);

  // Get page range for pagination controls
  const getPageRange = useCallback(
    (maxPages: number = 5): number[] => {
      if (totalPages <= maxPages) {
        return Array.from({ length: totalPages }, (_, i) => i + 1);
      }

      const half = Math.floor(maxPages / 2);
      let start = Math.max(1, currentPage - half);
      let end = Math.min(totalPages, start + maxPages - 1);

      // Adjust start if we're near the end
      if (end - start < maxPages - 1) {
        start = Math.max(1, end - maxPages + 1);
      }

      return Array.from({ length: end - start + 1 }, (_, i) => start + i);
    },
    [currentPage, totalPages]
  );

  // Return without useMemo wrapper (OPTIMIZED)
  return {
    currentPage,
    pageSize,
    totalCount,
    totalPages,
    startIndex,
    endIndex,
    hasPrevPage,
    hasNextPage,
    setCurrentPage,
    setPageSize,
    setTotalCount,
    nextPage,
    prevPage,
    firstPage,
    lastPage,
    reset,
    getPageRange,
  };
}
