import { z } from "zod";

/**
 * Shared JSON value type for streaming chunks.
 * Defined in a separate file to avoid circular dependencies.
 */
export type JsonValue =
  | string
  | number
  | boolean
  | null
  | JsonValue[]
  | { [key: string]: JsonValue };

export const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>
  z.union([
    z.string(),
    z.number(),
    z.boolean(),
    z.null(),
    z.array(JsonValueSchema),
    z.record(z.string(), JsonValueSchema),
  ]),
);

/**
 * Re-types a value as `JsonValue` without re-walking it. Use this ONLY when
 * the value has already been validated (e.g., via `SseEventSchema.safeParse`)
 * AND originated from `JSON.parse`. Skipping the recursive `JsonValueSchema`
 * walk avoids a second full-tree zod parse on every event of every streaming
 * response. Centralized here so the eslint-disable is one site, not two.
 */
export function trustAsJsonValue<T>(value: T): JsonValue {
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
  return value as unknown as JsonValue;
}
