import { FormikContextType, getIn, setIn } from 'formik';

function spliceArray<T>(arr: T[] | undefined, index: number) {
  const a = Array.isArray(arr) ? arr.slice() : [];
  if (index >= 0 && index < a.length) a.splice(index, 1);
  return a;
}

/**
 * Remove one item from an array field and also trim Formik's errors & touched
 * at the SAME index to keep everything aligned.
 *
 * @param formik - your useFormik instance
 * @param arrayPath - path to the array field, e.g. "kandangExpenses[0].expenses"
 * @param index - the index to remove
 * @param validateAfter - optional: revalidate after removal (default false)
 */
export async function removeArrayItemAndSync<FormValues>(
  formik: FormikContextType<FormValues>,
  arrayPath: string,
  index: number,
  validateAfter: boolean = false
) {
  // 1) VALUES: remove at index
  const currValues = getIn(formik.values, arrayPath);
  const nextValues = spliceArray(currValues, index);
  formik.setFieldValue(arrayPath, nextValues, false);

  // 2) ERRORS: remove the same index (if array exists)
  const currErrors = getIn(formik.errors, arrayPath);
  if (Array.isArray(currErrors)) {
    const nextErrors = spliceArray(currErrors, index);
    formik.setErrors(setIn(formik.errors, arrayPath, nextErrors));
  }

  // 3) TOUCHED: remove the same index (if array exists)
  const currTouched = getIn(formik.touched, arrayPath);
  if (Array.isArray(currTouched)) {
    const nextTouched = spliceArray(currTouched, index);
    formik.setTouched(setIn(formik.touched, arrayPath, nextTouched), false);
  }

  // 4) (optional) revalidate to rebuild a perfectly clean error tree
  if (validateAfter) {
    const newErrors = await formik.validateForm();
    formik.setErrors(newErrors);
  }
}
