/**
 * Zod Adapter - Converts Zod schemas to Formik validation functions
 * Provides type-safe form validation with Zod v4
 */

import * as z from 'zod';

/**
 * Converts a Zod schema to a Formik validate function
 *
 * @param schema - Zod schema to use for validation
 * @returns Formik-compatible validate function
 *
 * @example
 * ```typescript
 * const userSchema = z.object({
 *   email: z.string().email('Invalid email'),
 *   firstName: z.string().min(1, 'Required'),
 * })
 *
 * <Formik
 *   validate={toFormikValidate(userSchema)}
 *   initialValues={{ email: '', firstName: '' }}
 * >
 * ```
 */
export function toFormikValidate<T extends z.ZodType>(
  schema: T,
): (values: z.infer<T>) => Record<string, string> {
  return (values: z.infer<T>) => {
    const result = z.safeParse(schema, values);

    if (result.success) {
      return {};
    }

    const errors: Record<string, string> = {};

    if (result.error && 'issues' in result.error) {
      result.error.issues.forEach((issue) => {
        // Join path for nested fields (e.g., 'address.street')
        const path = issue.path.map(String).join('.');

        // Only set the first error for each field
        if (!errors[path]) {
          errors[path] = issue.message;
        }
      });
    }

    return errors;
  };
}

/**
 * Async version of toFormikValidate for schemas with async refinements
 *
 * @param schema - Zod schema to use for validation
 * @returns Formik-compatible async validate function
 */
export function toFormikValidateAsync<T extends z.ZodType>(
  schema: T,
): (values: z.infer<T>) => Promise<Record<string, string>> {
  return async (values: z.infer<T>) => {
    const result = await z.safeParseAsync(schema, values);

    if (result.success) {
      return {};
    }

    const errors: Record<string, string> = {};

    if (result.error && 'issues' in result.error) {
      result.error.issues.forEach((issue) => {
        const path = issue.path.map(String).join('.');

        if (!errors[path]) {
          errors[path] = issue.message;
        }
      });
    }

    return errors;
  };
}

export default toFormikValidate;
