import { z, ZodObject, ZodArray, ZodUnion, ZodIntersection, ZodRecord, ZodTuple, ZodLazy, ZodOptional, ZodNullable, ZodDefault, ZodMap, ZodSet, ZodPromise, ZodReadonly, ZodCatch, ZodPipe, ZodNonOptional, ZodPrefault } from "zod";
/**
 * A type utility that recursively makes all properties in a Zod schema optional.
 *
 * This type is the TypeScript counterpart to the `zodDeepPartial` function. It provides
 * proper type inference for deeply partial schemas, ensuring that:
 *
 * 1. All object properties become optional at all nesting levels
 * 2. Array element types are recursively made partial
 * 3. Union and intersection types are properly handled
 * 4. Record value types are made partial
 * 5. Tuple element types are made partial
 * 6. Lazy/recursive schemas maintain their recursive structure
 * 7. Optional and nullable wrappers are preserved
 * 8. Default values are preserved
 * 9. Map value types are made partial
 * 10. Set element types are made partial
 * 11. Promise inner types are made partial
 * 12. Readonly wrappers are preserved
 * 13. Catch wrappers are preserved
 * 14. Pipe schemas are preserved as-is (transforms have specific input requirements)
 * 15. NonOptional wrappers are preserved
 * 16. Prefault wrappers are preserved
 *
 * The type handles all Zod schema variants through a series of conditional type checks,
 * ensuring complete type safety when working with deeply partial schemas.
 *
 * @template T - The Zod schema type to make deeply partial
 *
 * @example
 * ```typescript
 * import { z } from "zod";
 * import type { DeepPartial } from "zod-deep-partial";
 *
 * const schema = z.object({
 *   name: z.string(),
 *   profile: z.object({
 *     bio: z.string(),
 *     age: z.number(),
 *   }),
 * });
 *
 * type PartialSchema = DeepPartial<typeof schema>;
 * // Results in a type where all properties are optional at all levels
 * ```
 */
export type DeepPartial<T extends z.core.SomeType> = T extends ZodOptional<infer Inner> ? ZodOptional<DeepPartial<Inner>> : T extends ZodNullable<infer Inner> ? ZodNullable<DeepPartial<Inner>> : T extends ZodDefault<infer Inner> ? ZodDefault<DeepPartial<Inner>> : T extends ZodCatch<infer Inner> ? ZodCatch<DeepPartial<Inner>> : T extends ZodPrefault<infer Inner> ? ZodPrefault<DeepPartial<Inner>> : T extends ZodNonOptional<infer Inner> ? ZodNonOptional<DeepPartial<Inner>> : T extends ZodReadonly<infer Inner> ? ZodReadonly<DeepPartial<Inner>> : T extends ZodObject<infer Shape> ? ZodObject<{
    [K in keyof Shape]: ZodOptional<DeepPartial<Shape[K]>>;
}> : T extends ZodArray<infer Type> ? ZodArray<DeepPartial<Type>> : T extends ZodMap<infer Key, infer Value> ? ZodMap<Key, DeepPartial<Value>> : T extends ZodSet<infer Type> ? ZodSet<DeepPartial<Type>> : T extends ZodPromise<infer Type> ? ZodPromise<DeepPartial<Type>> : T extends ZodUnion<infer Options> ? ZodUnion<{
    [K in keyof Options]: DeepPartial<Options[K]>;
}> : T extends ZodIntersection<infer Left, infer Right> ? ZodIntersection<DeepPartial<Left>, DeepPartial<Right>> : T extends ZodRecord<infer Key, infer Value> ? ZodRecord<Key, DeepPartial<Value>> : T extends ZodTuple<infer Items> ? ZodTuple<{
    [K in keyof Items]: DeepPartial<Items[K]>;
} extends infer U ? U extends any[] ? U : never : never> : T extends ZodPipe<infer In, infer Out> ? ZodPipe<In, Out> : T extends ZodLazy<infer Type> ? ZodLazy<DeepPartial<Type>> : ZodOptional<T>;
