import { useCallback, useMemo, useRef } from 'react'; import { validationRules } from '../constants/validation'; import { buildColumnHeaderPaths, collectInvalidErrors, isValidationRuleEnabled } from '../utils/validationUtils'; const EMPTY_ARRAY = []; export const useValidationRules = (data, columns, formType, sheetName) => { const safeData = data || EMPTY_ARRAY; const safeColumns = columns || EMPTY_ARRAY; const stableErrorsRef = useRef([]); const headerPaths = useMemo(() => buildColumnHeaderPaths(safeColumns), [safeColumns]); const activeRules = useMemo( () => validationRules.filter((rule) => isValidationRuleEnabled(rule, { formType, sheetName })), [formType, sheetName], ); const calculatedErrors = useMemo(() => { const result = []; const seen = new Set(); for (const rule of activeRules) { collectInvalidErrors(safeData, rule, headerPaths, result, seen); } return result; }, [activeRules, headerPaths, safeData]); const previousErrors = stableErrorsRef.current; const errorsAreEqual = previousErrors.length === calculatedErrors.length && previousErrors.every( (error, index) => error.id === calculatedErrors[index].id && error.columnId === calculatedErrors[index].columnId && error.message === calculatedErrors[index].message, ); if (!errorsAreEqual) { stableErrorsRef.current = calculatedErrors; } const errors = stableErrorsRef.current; const isCellInvalid = useCallback( (columnId, value, row) => activeRules.some( (rule) => rule.columnKeys.includes(columnId) && (!rule.appliesToRow || rule.appliesToRow(row)) && rule.isInvalid(value, row, columnId), ), [activeRules], ); return { errors, isCellInvalid, headerPaths }; };