/**
 * 分页 Hook
 * 
 * 提供 React 组件中使用的分页功能，包括：
 * - loadMore: 加载更多数据
 * - refresh: 刷新数据
 * - prefetch: 预加载数据
 * - 自动预加载检测
 * - 分页状态管理
 */

import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
import {
  paginationStateManager,
  PaginationState,
  PaginationConfig,
  LoadMoreResult,
  RefreshResult,
  PrefetchResult,
  FetchPageFunction,
  DEFAULT_PAGINATION_CONFIG,
} from '../infrastructure/pagination';

/**
 * usePagination 选项
 */
export interface UsePaginationOptions<T = any> {
  /** 分页键（通常是会话ID或列表标识） */
  key: string | null;
  /** 数据获取函数 */
  fetchFunction: FetchPageFunction<T>;
  /** 分页配置 */
  config?: Partial<PaginationConfig>;
  /** 初始数据 */
  initialData?: T[];
  /** 是否自动加载第一页 */
  autoLoad?: boolean;
  /** 是否启用自动预加载 */
  enableAutoPrefetch?: boolean;
}

/**
 * usePagination 返回值
 */
export interface UsePaginationReturn<T = any> {
  /** 当前数据列表 */
  data: T[];
  /** 是否正在加载 */
  isLoading: boolean;
  /** 是否正在刷新 */
  isRefreshing: boolean;
  /** 是否有更多数据 */
  hasMore: boolean;
  /** 是否发生过错误 */
  hasError: boolean;
  /** 错误信息 */
  error?: string;
  /** 当前页码 */
  currentPage: number;
  /** 已加载的总数 */
  totalLoaded: number;
  /** 加载更多 */
  loadMore: () => Promise<LoadMoreResult<T>>;
  /** 刷新数据 */
  refresh: () => Promise<RefreshResult<T>>;
  /** 预加载指定页面 */
  prefetch: (page: number) => Promise<PrefetchResult<T>>;
  /** 重置分页状态 */
  reset: () => void;
  /** 手动设置数据 */
  setData: (data: T[]) => void;
  /** 追加数据 */
  appendData: (data: T[]) => void;
}

/**
 * 分页 Hook
 * 
 * 示例用法：
 * ```typescript
 * const {
 *   data,
 *   isLoading,
 *   hasMore,
 *   loadMore,
 *   refresh,
 * } = usePagination<Message>({
 *   key: conversationId,
 *   fetchFunction: async (page, pageSize, cursor) => {
 *     const result = await messageService.getMessages({
 *       page,
 *       pageSize,
 *       beforeSeq: cursor,
 *     });
 *     return {
 *       data: result.messages,
 *       hasMore: result.has_more,
 *       cursor: result.min_seq,
 *     };
 *   },
 *   config: { pageSize: 20 },
 * });
 * ```
 */
export function usePagination<T = any>(
  options: UsePaginationOptions<T>
): UsePaginationReturn<T> {
  const {
    key,
    fetchFunction,
    config: userConfig,
    initialData = [],
    autoLoad = false,
    enableAutoPrefetch = true,
  } = options;

  // 合并配置
  const config = useMemo(() => ({
    ...DEFAULT_PAGINATION_CONFIG,
    ...userConfig,
  }), [userConfig]);

  // 内部数据状态
  const [data, setData] = useState<T[]>(initialData);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [lastError, setLastError] = useState<string | undefined>(undefined);

  // 用于追踪是否已自动加载
  const autoLoadRef = useRef(false);
  
  // 用于追踪组件是否已卸载
  const isMountedRef = useRef(true);

  // 获取当前分页状态
  const paginationState = useMemo(() => {
    if (!key) return null;
    return paginationStateManager.getState(key, config);
  }, [key, config]);

  // 计算派生状态
  const isLoading = paginationState?.isLoading ?? false;
  const hasMore = paginationState?.hasMore ?? true;
  const currentPage = paginationState?.currentPage ?? 0;
  const totalLoaded = paginationState?.totalLoaded ?? 0;
  const hasError = paginationState?.hasError ?? false;
  const error = paginationState?.error ?? lastError;

  // 当 key 变化时重置数据
  useEffect(() => {
    if (key) {
      setData(initialData);
      autoLoadRef.current = false;
    }
  }, [key]);

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      isMountedRef.current = false;
    };
  }, []);

  // 自动加载第一页
  useEffect(() => {
    if (!key || !autoLoad || autoLoadRef.current) return;
    if (data.length > 0) return;

    autoLoadRef.current = true;
    refresh();
  }, [key, autoLoad, data.length]);

  // 自动预加载检测
  useEffect(() => {
    if (!key || !enableAutoPrefetch) return;
    if (!paginationStateManager.shouldPrefetch(key, data.length)) return;

    // 触发预加载
    const prefetchNextPage = async () => {
      const nextPage = currentPage + 1;
      await paginationStateManager.prefetch(key, nextPage, fetchFunction);
    };

    prefetchNextPage();
  }, [key, data.length, currentPage, enableAutoPrefetch, fetchFunction]);

  /**
   * 加载更多数据
   */
  const loadMore = useCallback(async (): Promise<LoadMoreResult<T>> => {
    if (!key) {
      return {
        success: false,
        data: [],
        hasMore: false,
        fromCache: false,
        error: 'No pagination key provided',
      };
    }

    const result = await paginationStateManager.loadMore<T>(key, fetchFunction);

    if (isMountedRef.current) {
      if (result.success) {
        setData(prev => [...prev, ...result.data]);
        setLastError(undefined);
      } else if (result.error) {
        setLastError(result.error);
      }
    }

    return result;
  }, [key, fetchFunction]);

  /**
   * 刷新数据
   */
  const refresh = useCallback(async (): Promise<RefreshResult<T>> => {
    if (!key) {
      return {
        success: false,
        data: [],
        hasMore: false,
        error: 'No pagination key provided',
      };
    }

    setIsRefreshing(true);

    try {
      const result = await paginationStateManager.refresh<T>(key, fetchFunction);

      if (isMountedRef.current) {
        if (result.success) {
          setData(result.data);
          setLastError(undefined);
        } else if (result.error) {
          setLastError(result.error);
        }
      }

      return result;
    } finally {
      if (isMountedRef.current) {
        setIsRefreshing(false);
      }
    }
  }, [key, fetchFunction]);

  /**
   * 预加载指定页面
   */
  const prefetch = useCallback(async (page: number): Promise<PrefetchResult<T>> => {
    if (!key) {
      return {
        success: false,
        error: 'No pagination key provided',
      };
    }

    return paginationStateManager.prefetch<T>(key, page, fetchFunction);
  }, [key, fetchFunction]);

  /**
   * 重置分页状态
   */
  const reset = useCallback(() => {
    if (!key) return;

    paginationStateManager.reset(key, config);
    if (isMountedRef.current) {
      setData([]);
      setLastError(undefined);
      autoLoadRef.current = false;
    }
  }, [key, config]);

  /**
   * 手动设置数据
   */
  const setDataManual = useCallback((newData: T[]) => {
    if (isMountedRef.current) {
      setData(newData);
    }
  }, []);

  /**
   * 追加数据
   */
  const appendData = useCallback((newData: T[]) => {
    if (isMountedRef.current) {
      setData(prev => [...prev, ...newData]);
    }
  }, []);

  return {
    data,
    isLoading,
    isRefreshing,
    hasMore,
    hasError,
    error,
    currentPage,
    totalLoaded,
    loadMore,
    refresh,
    prefetch,
    reset,
    setData: setDataManual,
    appendData,
  };
}

/**
 * 使用分页状态管理器的单例实例
 * 用于在组件外访问分页状态
 */
export function usePaginationManager() {
  return paginationStateManager;
}

export default usePagination;
