/**
 * useSorting Hook
 *
 * A composable hook for managing sorting state with support for
 * single-column sorting and optional multi-column sorting.
 *
 * @example
 * ```tsx
 * const sorting = useSorting<'name' | 'email' | 'createdAt'>({
 *   initialField: 'name',
 *   initialDirection: 'asc',
 * });
 *
 * return (
 *   <table>
 *     <thead>
 *       <tr>
 *         <th onClick={() => sorting.sortBy('name')}>
 *           Name {sorting.getSortDirection('name') === 'asc' ? '↑' : sorting.getSortDirection('name') === 'desc' ? '↓' : ''}
 *         </th>
 *         <th onClick={() => sorting.sortBy('email')}>
 *           Email {sorting.getSortDirection('email') === 'asc' ? '↑' : sorting.getSortDirection('email') === 'desc' ? '↓' : ''}
 *         </th>
 *       </tr>
 *     </thead>
 *   </table>
 * );
 * ```
 *
 * ⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
 */

import { useState, useCallback, useMemo } from 'react';
import type {
  SortDirection,
  SortingOptions,
  SortEntry,
  SortingState,
  SortingActions,
  UseSortingResult,
} from '../types';

/**
 * Hook for managing sorting state.
 *
 * @param options - Sorting options
 * @returns Sorting state and actions
 */
export function useSorting<TField = string>(
  options: SortingOptions<TField> = {}
): UseSortingResult<TField> {
  const {
    initialField,
    initialDirection = 'asc',
    multiSort = false,
  } = options;

  // For single sort mode, we track field and direction
  // For multi sort mode, we track an array of sort entries
  const [sorts, setSorts] = useState<SortEntry<TField>[]>(() => {
    if (initialField !== undefined) {
      return [{ field: initialField, direction: initialDirection }];
    }
    return [];
  });

  // Computed values
  const field = sorts.length > 0 ? sorts[0].field : null;
  const direction = sorts.length > 0 ? sorts[0].direction : 'asc';
  const isSorted = sorts.length > 0;

  // Actions
  const getSortDirection = useCallback(
    (targetField: TField): SortDirection | null => {
      const entry = sorts.find((s) => s.field === targetField);
      return entry?.direction ?? null;
    },
    [sorts]
  );

  const setSort = useCallback(
    (targetField: TField, targetDirection: SortDirection) => {
      if (multiSort) {
        setSorts((prev) => {
          const existing = prev.findIndex((s) => s.field === targetField);
          if (existing !== -1) {
            // Update existing
            const newSorts = [...prev];
            newSorts[existing] = { field: targetField, direction: targetDirection };
            return newSorts;
          }
          // Add new
          return [...prev, { field: targetField, direction: targetDirection }];
        });
      } else {
        setSorts([{ field: targetField, direction: targetDirection }]);
      }
    },
    [multiSort]
  );

  const sortBy = useCallback(
    (targetField: TField) => {
      const currentDirection = getSortDirection(targetField);

      if (currentDirection === null) {
        // Not currently sorted by this field, sort ascending
        setSort(targetField, 'asc');
      } else if (currentDirection === 'asc') {
        // Currently ascending, switch to descending
        setSort(targetField, 'desc');
      } else {
        // Currently descending, clear sort
        if (multiSort) {
          setSorts((prev) => prev.filter((s) => s.field !== targetField));
        } else {
          setSorts([]);
        }
      }
    },
    [getSortDirection, setSort, multiSort]
  );

  const clearSort = useCallback(() => {
    setSorts([]);
  }, []);

  const reset = useCallback(() => {
    if (initialField !== undefined) {
      setSorts([{ field: initialField, direction: initialDirection }]);
    } else {
      setSorts([]);
    }
  }, [initialField, initialDirection]);

  // Build state object
  const state: SortingState<TField> = {
    field,
    direction,
    sorts,
    isSorted,
  };

  // Build actions object
  const actions: SortingActions<TField> = {
    sortBy,
    setSort,
    clearSort,
    getSortDirection,
    reset,
  };

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

export default useSorting;
