import { ZodError } from 'zod';
import { $ZodIssue } from 'zod/v4/core';

/**
 * Converts a path array to a dot-separated string with [index] style.
 */
const formatPath = (path: Array<PropertyKey>): string =>
  path
    .map((segment) => (typeof segment === 'number' ? `[${segment}]` : segment))
    .join('.')
    .replace(/\.?(\[\d+\])\.?/g, (match) => match);

/**
 * Formats a single error object to a readable message.
 */
const formatSingleError = (issue: $ZodIssue): string => {
  if (issue.path && issue.path.length > 0) {
    const pathStr = formatPath(issue.path);
    return `Validation error at ${pathStr}: ${issue.message}`;
  }
  return issue.message;
};

/**
 * Formats an array of validation issues into a single string.
 */
const formatIssues = (issues: $ZodIssue[]): string =>
  issues.reduce(
    (acc, issue, index) =>
      `${acc}${index > 0 ? '\n' : ''}${formatSingleError(issue)}`,
    '',
  );

/**
 * Detects a ZodError and formats error messages.
 * This is the main function that should be used in catch blocks.
 */
export const transformZodErrors = (error: any): Error => {
  if (error instanceof ZodError) {
    const formattedMessage = formatIssues(error.issues);
    return new Error(formattedMessage || 'Validation error occurred');
  }
  return error;
};
