import { z } from 'zod';

import { useForm } from '@inertiajs/react';

import { useFormValidation } from './useFormValidation';

type SchemaWithShape = z.ZodObject<z.ZodRawShape>;

/**
 * DEBT-006: Combines Inertia's useForm with optional Zod client-side validation.
 *
 * Returns all of Inertia's useForm properties plus `clientErrors` which contains
 * Zod validation errors for instant client-side feedback before server round-trip.
 * Server errors from Inertia are available via the existing `errors` property.
 *
 * Usage (with schema):
 *   const schema = z.object({ name: z.string().min(1), domain: z.string().url() });
 *   const { data, setData, post, processing, errors, clientErrors, validateField } =
 *     useFormWithValidation({ name: '', domain: '' }, schema);
 *
 * Usage (without schema — behaves identically to useForm):
 *   const form = useFormWithValidation({ name: '' });
 */
export function useFormWithValidation<
  TForm extends Record<string, unknown>,
  TSchema extends SchemaWithShape = SchemaWithShape,
>(initialData: TForm, schema?: TSchema) {
  // Cast needed because useForm's FormDataType constraint is stricter than Record<string, unknown>
  const form = useForm(initialData as unknown as Record<string, string>);

  // useFormValidation returns a no-op if no schema is provided — we handle that
  // by always calling hooks (React rules) but making schema optional at type level.
  const placeholderSchema = (schema ?? z.object({})) as SchemaWithShape;
  const {
    errors: clientErrors,
    validateField,
    validateAll,
    clearError,
  } = useFormValidation(placeholderSchema);

  return {
    ...form,
    /** Client-side Zod validation errors (distinct from server `errors`). */
    clientErrors: schema ? clientErrors : ({} as Partial<Record<keyof TForm, string>>),
    /** Validates a single field against the Zod schema immediately. */
    validateField: schema ? validateField : () => undefined,
    /** Validates all fields; returns true if valid. */
    validateAll: schema ? validateAll : () => true,
    /** Clears a single client-side error. */
    clearClientError: schema ? clearError : () => undefined,
  };
}
