/**
 * Lightweight Zod → JSON Schema converter for MCP tool registration.
 *
 * Handles the subset of Zod types used by Reonomy tools:
 * ZodObject, ZodString, ZodNumber, ZodBoolean, ZodEnum, ZodArray,
 * ZodOptional, ZodDefault, ZodLiteral.
 */

import { z, type ZodType } from "zod";

type JsonSchema = Record<string, unknown>;

export function zodToJsonSchema(schema: ZodType): JsonSchema {
  return convertType(schema);
}

function convertType(schema: ZodType): JsonSchema {
  // Unwrap ZodOptional
  if (schema instanceof z.ZodOptional) {
    return convertType(schema.unwrap());
  }

  // Unwrap ZodDefault
  if (schema instanceof z.ZodDefault) {
    const inner = convertType(schema._def.innerType);
    if (schema._def.defaultValue !== undefined) {
      inner.default = typeof schema._def.defaultValue === "function"
        ? schema._def.defaultValue()
        : schema._def.defaultValue;
    }
    return inner;
  }

  // ZodObject
  if (schema instanceof z.ZodObject) {
    const shape = schema.shape as Record<string, ZodType>;
    const properties: Record<string, JsonSchema> = {};
    const required: string[] = [];

    for (const [key, value] of Object.entries(shape)) {
      properties[key] = convertType(value);

      // Add description from .describe()
      const desc = (value as any)._def?.description;
      if (desc) properties[key].description = desc;

      // Track required (non-optional) fields
      if (!(value instanceof z.ZodOptional) && !(value instanceof z.ZodDefault)) {
        required.push(key);
      }
    }

    const result: JsonSchema = { type: "object", properties };
    if (required.length > 0) result.required = required;
    return result;
  }

  // ZodString
  if (schema instanceof z.ZodString) {
    const result: JsonSchema = { type: "string" };
    const desc = (schema as any)._def?.description;
    if (desc) result.description = desc;
    return result;
  }

  // ZodNumber
  if (schema instanceof z.ZodNumber) {
    const result: JsonSchema = { type: "number" };
    const desc = (schema as any)._def?.description;
    if (desc) result.description = desc;
    return result;
  }

  // ZodBoolean
  if (schema instanceof z.ZodBoolean) {
    const result: JsonSchema = { type: "boolean" };
    const desc = (schema as any)._def?.description;
    if (desc) result.description = desc;
    return result;
  }

  // ZodEnum
  if (schema instanceof z.ZodEnum) {
    return { type: "string", enum: schema.options };
  }

  // ZodLiteral
  if (schema instanceof z.ZodLiteral) {
    return { type: typeof schema.value, const: schema.value };
  }

  // ZodArray
  if (schema instanceof z.ZodArray) {
    return { type: "array", items: convertType(schema.element) };
  }

  // ZodUnion
  if (schema instanceof z.ZodUnion) {
    const options = (schema as any)._def.options as ZodType[];
    return { oneOf: options.map(convertType) };
  }

  // Fallback
  return {};
}
