/* eslint-disable sonarjs/cognitive-complexity */ import { debouncedReaction } from '../utils/mobx'; import type { ProcessContext } from './types'; import type { Elements } from '@/Components/Calculation/config/map/values'; import type { Values } from '@/stores/calculation/values/types'; import ValidationHelper from '@/stores/validation/helper'; import { comparer, toJS } from 'mobx'; import { uid } from 'radash'; import type { ZodTypeAny } from 'zod'; export function createValidationReaction( createValidationSchema: (context: ProcessContext) => T, opts?: { fireImmediately: boolean } ) { const key = uid(7); return (context: ProcessContext) => { const validationSchema = createValidationSchema(context); const shapeValues = Object.keys(validationSchema._def.schema.shape) as string[]; const { store } = context; const { $calculation, $tables } = store; const helper = new ValidationHelper(); debouncedReaction( () => { const values = $calculation.$values.getValues(shapeValues as Values[]); if (shapeValues.includes('insurance')) return { ...values, insurance: { values: { fingap: toJS($tables.insurance.row('fingap').getValues()), kasko: toJS($tables.insurance.row('kasko').getValues()), osago: toJS($tables.insurance.row('osago').getValues()), }, }, }; if (shapeValues.includes('payments')) { return { ...values, payments: { values: toJS($tables.payments.values) }, }; } return values; }, async (values) => { helper.removeErrors(); const validationResult = await validationSchema.safeParseAsync(values); if (validationResult.success === false) { validationResult.error.errors.forEach(({ path, message }) => { ( path as Array ).forEach((elementName) => { if (elementName === 'insurance') { const removeError = $tables.insurance.setError({ key, message }); if (removeError) helper.add(removeError); } else if (elementName === 'payments') { const removeError = $tables.payments.setError({ key, message }); if (removeError) helper.add(removeError); } else if (elementName === 'eltOsago') { const removeError = $tables.elt.osago.validation.setError({ key, message, silent: true, }); if (removeError) helper.add(removeError); } else if (elementName === 'eltKasko') { const removeError = $tables.elt.kasko.validation.setError({ key, message, silent: true, }); if (removeError) helper.add(removeError); } else { const removeError = $calculation.element(elementName).setError({ key, message }); if (removeError) helper.add(removeError); } }); }); } else { helper.removeErrors(); } }, { delay: 1, equals: comparer.structural, fireImmediately: opts?.fireImmediately, wait: 100, } ); }; }