/**
 * usePagination Hook
 *
 * A composable hook for managing pagination state.
 *
 * @example
 * ```tsx
 * const pagination = usePagination({ initialPageSize: 20, totalItems: 100 });
 *
 * return (
 *   <div>
 *     <div>Page {pagination.page} of {pagination.totalPages}</div>
 *     <button onClick={pagination.previousPage} disabled={!pagination.hasPreviousPage}>
 *       Previous
 *     </button>
 *     <button onClick={pagination.nextPage} disabled={!pagination.hasNextPage}>
 *       Next
 *     </button>
 *   </div>
 * );
 * ```
 *
 * ⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
 */

import { useState, useCallback, useMemo } from 'react';
import type {
  PaginationOptions,
  PaginationState,
  PaginationActions,
  UsePaginationResult,
} from '../types';

const DEFAULT_PAGE = 1;
const DEFAULT_PAGE_SIZE = 20;
const DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];

/**
 * Hook for managing pagination state.
 *
 * @param options - Pagination options
 * @returns Pagination state and actions
 */
export function usePagination(options: PaginationOptions = {}): UsePaginationResult {
  const {
    initialPage = DEFAULT_PAGE,
    initialPageSize = DEFAULT_PAGE_SIZE,
    pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
    totalItems: initialTotalItems = 0,
  } = options;

  const [page, setPageState] = useState(initialPage);
  const [pageSize, setPageSizeState] = useState(initialPageSize);
  const [totalItems, setTotalItemsState] = useState(initialTotalItems);

  // Computed values
  const totalPages = useMemo(
    () => Math.max(1, Math.ceil(totalItems / pageSize)),
    [totalItems, pageSize]
  );

  const hasPreviousPage = page > 1;
  const hasNextPage = page < totalPages;

  const startIndex = useMemo(
    () => Math.min((page - 1) * pageSize, Math.max(0, totalItems - 1)),
    [page, pageSize, totalItems]
  );

  const endIndex = useMemo(
    () => Math.min(page * pageSize - 1, totalItems - 1),
    [page, pageSize, totalItems]
  );

  // Actions
  const setPage = useCallback(
    (newPage: number) => {
      const clampedPage = Math.max(1, Math.min(newPage, totalPages));
      setPageState(clampedPage);
    },
    [totalPages]
  );

  const nextPage = useCallback(() => {
    if (hasNextPage) {
      setPageState((p) => p + 1);
    }
  }, [hasNextPage]);

  const previousPage = useCallback(() => {
    if (hasPreviousPage) {
      setPageState((p) => p - 1);
    }
  }, [hasPreviousPage]);

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

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

  const setPageSize = useCallback((size: number) => {
    setPageSizeState(size);
    // Reset to first page when page size changes
    setPageState(1);
  }, []);

  const setTotalItems = useCallback((total: number) => {
    setTotalItemsState(Math.max(0, total));
  }, []);

  const reset = useCallback(() => {
    setPageState(initialPage);
    setPageSizeState(initialPageSize);
    setTotalItemsState(initialTotalItems);
  }, [initialPage, initialPageSize, initialTotalItems]);

  // Build state object
  const state: PaginationState = {
    page,
    pageSize,
    totalItems,
    totalPages,
    hasPreviousPage,
    hasNextPage,
    startIndex,
    endIndex,
  };

  // Build actions object
  const actions: PaginationActions = {
    setPage,
    nextPage,
    previousPage,
    firstPage,
    lastPage,
    setPageSize,
    setTotalItems,
    reset,
  };

  return {
    ...state,
    ...actions,
    pageSizeOptions,
  };
}

export default usePagination;
