'use strict';

const z = require('zod');

function zodToFormSchema(schema, metadata) {
  const jsonSchema = z.z.toJSONSchema(schema, {
    unrepresentable: "any",
    override: (ctx) => {
      const def = ctx.zodSchema?._zod?.def;
      if (def?.type === "date") {
        ctx.jsonSchema.type = "string";
        ctx.jsonSchema.format = "date-time";
        const zodSchema = ctx.zodSchema;
        if (zodSchema.minDate) {
          ctx.jsonSchema.formatMinimum = zodSchema.minDate;
        }
        if (zodSchema.maxDate) {
          ctx.jsonSchema.formatMaximum = zodSchema.maxDate;
        }
      }
    }
  });
  if (metadata?.steps) {
    jsonSchema.steps = metadata.steps;
  }
  if (metadata?.stepGroupMap) {
    jsonSchema.stepGroupMap = metadata.stepGroupMap;
  }
  return jsonSchema;
}
function extractStepGroupMap(jsonSchema) {
  const stepGroupMap = {};
  const properties = jsonSchema.properties;
  if (!properties) return stepGroupMap;
  for (const [fieldName, fieldSchema] of Object.entries(properties)) {
    if (typeof fieldSchema.stepGroup === "number") {
      stepGroupMap[fieldName] = fieldSchema.stepGroup;
    }
  }
  return stepGroupMap;
}
function findDateFieldsWithConstraints(jsonSchema) {
  const dateFields = {};
  const properties = jsonSchema.properties;
  if (!properties) return dateFields;
  for (const [key, prop] of Object.entries(properties)) {
    if (prop.type === "string" && prop.format === "date-time") {
      if (prop.formatMinimum || prop.formatMaximum) {
        dateFields[key] = {
          min: prop.formatMinimum,
          max: prop.formatMaximum
        };
      }
    }
  }
  return dateFields;
}
function addDateValidations(schema, dateFieldsWithConstraints) {
  if (Object.keys(dateFieldsWithConstraints).length === 0) {
    return schema;
  }
  return schema.superRefine((data, ctx) => {
    for (const [key, constraints] of Object.entries(dateFieldsWithConstraints)) {
      const value = data[key];
      if (value === void 0 || value === null || value === "") continue;
      const dateValue = new Date(value);
      if (isNaN(dateValue.getTime())) {
        ctx.addIssue({
          code: z.z.ZodIssueCode.custom,
          message: "Invalid date",
          path: [key]
        });
        continue;
      }
      if (constraints.min) {
        const minDate = new Date(constraints.min);
        if (dateValue < minDate) {
          ctx.addIssue({
            code: z.z.ZodIssueCode.custom,
            message: `Date must be after ${minDate.toLocaleDateString()}`,
            path: [key]
          });
        }
      }
      if (constraints.max) {
        const maxDate = new Date(constraints.max);
        if (dateValue > maxDate) {
          ctx.addIssue({
            code: z.z.ZodIssueCode.custom,
            message: `Date must be before ${maxDate.toLocaleDateString()}`,
            path: [key]
          });
        }
      }
    }
  });
}
function attachStepsMetadata(schema, jsonSchema) {
  const steps = jsonSchema.steps;
  if (!steps || steps.length === 0) {
    return schema;
  }
  const stepGroupMap = jsonSchema.stepGroupMap ?? extractStepGroupMap(jsonSchema);
  return schema.meta({
    steps,
    stepGroupMap
  });
}
function formSchemaToZod(jsonSchema) {
  let schema = z.z.fromJSONSchema(jsonSchema);
  const dateFieldsWithConstraints = findDateFieldsWithConstraints(jsonSchema);
  schema = addDateValidations(schema, dateFieldsWithConstraints);
  schema = attachStepsMetadata(schema, jsonSchema);
  return schema;
}
function hasSteps(jsonSchema) {
  return Array.isArray(jsonSchema.steps) && jsonSchema.steps.length > 0;
}
function getSteps(jsonSchema) {
  return jsonSchema.steps ?? [];
}
function getStepGroupMap(jsonSchema) {
  return jsonSchema.stepGroupMap ?? extractStepGroupMap(jsonSchema);
}

exports.formSchemaToZod = formSchemaToZod;
exports.getStepGroupMap = getStepGroupMap;
exports.getSteps = getSteps;
exports.hasSteps = hasSteps;
exports.zodToFormSchema = zodToFormSchema;
