'use strict';

const jsxRuntime = require('react/jsx-runtime');
require('zod');

const BUILTIN_FIELD_TYPES = [
  "checkbox",
  "date",
  "select",
  "radio",
  "switch",
  "textarea",
  "number",
  "fallback"
];
function getDefTypeName(schema) {
  const def = schema._zod?.def;
  return def?.type || "";
}
function beautifyObjectName(string) {
  let output = string.replace(/([A-Z])/g, " $1");
  output = output.charAt(0).toUpperCase() + output.slice(1);
  return output;
}
function getBaseSchema(schema) {
  if (!schema) return null;
  const def = schema._zod?.def;
  if (!def) return schema;
  if (def.innerType) {
    return getBaseSchema(def.innerType);
  }
  if (def.out) {
    return getBaseSchema(def.out);
  }
  if (def.schema) {
    return getBaseSchema(def.schema);
  }
  return schema;
}
function getBaseType(schema) {
  const baseSchema = getBaseSchema(schema);
  if (!baseSchema) return "";
  const typeName = getDefTypeName(baseSchema);
  const typeMap = {
    object: "ZodObject",
    array: "ZodArray",
    string: "ZodString",
    number: "ZodNumber",
    int: "ZodNumber",
    float: "ZodNumber",
    boolean: "ZodBoolean",
    date: "ZodDate",
    enum: "ZodEnum",
    nativeEnum: "ZodNativeEnum",
    literal: "ZodLiteral",
    union: "ZodUnion"
  };
  return typeMap[typeName] || typeName;
}
function getDefaultValueInZodStack(schema) {
  const def = schema._zod?.def;
  if (!def) return void 0;
  if (def.type === "default") {
    const defaultValue = def.defaultValue;
    if (typeof defaultValue === "function") {
      return defaultValue();
    }
    return defaultValue;
  }
  if (def.innerType) {
    return getDefaultValueInZodStack(def.innerType);
  }
  if (def.schema) {
    return getDefaultValueInZodStack(def.schema);
  }
  return void 0;
}
function getDefaultValues(schema, fieldConfig) {
  if (!schema) return null;
  const { shape } = schema;
  const defaultValues = {};
  if (!shape) return defaultValues;
  for (const key of Object.keys(shape)) {
    const item = shape[key];
    if (getBaseType(item) === "ZodObject") {
      const defaultItems = getDefaultValues(
        getBaseSchema(item),
        fieldConfig?.[key]
      );
      if (defaultItems !== null) {
        for (const defaultItemKey of Object.keys(defaultItems)) {
          const pathKey = `${key}.${defaultItemKey}`;
          defaultValues[pathKey] = defaultItems[defaultItemKey];
        }
      }
    } else {
      let defaultValue = getDefaultValueInZodStack(item);
      if ((defaultValue === void 0 || defaultValue === null || defaultValue === "") && fieldConfig?.[key]?.inputProps) {
        defaultValue = (fieldConfig?.[key]?.inputProps).defaultValue;
      }
      if (defaultValue !== void 0) {
        defaultValues[key] = defaultValue;
      }
    }
  }
  return defaultValues;
}
function getObjectFormSchema(schema) {
  if (!schema) return schema;
  const def = schema._zod?.def;
  if (!def) return schema;
  if (def.type === "pipe") {
    return getObjectFormSchema(def.in);
  }
  if (def.innerType) {
    return getObjectFormSchema(def.innerType);
  }
  if (def.schema) {
    return getObjectFormSchema(def.schema);
  }
  return schema;
}
function zodToHtmlInputProps(schema) {
  const def = schema._zod?.def;
  const defType = def?.type || "";
  if (["optional", "nullable"].includes(defType)) {
    return {
      ...zodToHtmlInputProps(def.innerType),
      required: false
    };
  }
  if (defType === "default") {
    return {
      ...zodToHtmlInputProps(def.innerType),
      required: false
    };
  }
  const inputProps = {
    required: true
  };
  const checks = def?.checks;
  if (!checks || !Array.isArray(checks)) {
    return inputProps;
  }
  const type = getBaseType(schema);
  for (const check of checks) {
    const checkKind = check.kind || check.type;
    if (checkKind === "min" || checkKind === "min_length") {
      if (type === "ZodString") {
        inputProps.minLength = check.value ?? check.minimum;
      } else {
        inputProps.min = check.value ?? check.minimum;
      }
    }
    if (checkKind === "max" || checkKind === "max_length") {
      if (type === "ZodString") {
        inputProps.maxLength = check.value ?? check.maximum;
      } else {
        inputProps.max = check.value ?? check.maximum;
      }
    }
  }
  return inputProps;
}
function sortFieldsByOrder(fieldConfig, keys) {
  const sortedFields = keys.sort((a, b) => {
    const fieldA = fieldConfig?.[a]?.order ?? 0;
    const fieldB = fieldConfig?.[b]?.order ?? 0;
    return fieldA - fieldB;
  });
  return sortedFields;
}
function buildFieldConfigFromJsonSchema(jsonSchema, fieldComponents) {
  const fieldConfig = {};
  const properties = jsonSchema.properties;
  if (!properties) return fieldConfig;
  for (const [key, value] of Object.entries(properties)) {
    const config = {};
    if (value.label) {
      config.label = value.label;
    } else if (value.title) {
      config.label = value.title;
    }
    if (value.description) {
      config.description = value.description;
    }
    const inputProps = value.inputProps ? { ...value.inputProps } : {};
    if (value.placeholder) {
      inputProps.placeholder = value.placeholder;
    }
    if (value.default !== void 0) {
      inputProps.defaultValue = value.default;
      inputProps.required = false;
    }
    if (Object.keys(inputProps).length > 0) {
      config.inputProps = inputProps;
    }
    if (value.order !== void 0) {
      config.order = value.order;
    }
    let fieldType = value.fieldType;
    if (!fieldType && value.type === "string" && value.format === "date-time") {
      fieldType = "date";
    }
    if (fieldType) {
      const CustomComponent = fieldComponents?.[fieldType];
      if (CustomComponent) {
        config.fieldType = (props) => /* @__PURE__ */ jsxRuntime.jsx(CustomComponent, { ...props });
      } else if (BUILTIN_FIELD_TYPES.includes(
        fieldType
      )) {
        config.fieldType = fieldType;
      } else {
        console.warn(
          `CMS: Unknown fieldType "${fieldType}" for field "${key}". Provide a component via fieldComponents override or use a built-in type.`
        );
      }
    }
    if (value.properties) {
      const nestedConfig = buildFieldConfigFromJsonSchema(
        { properties: value.properties },
        fieldComponents
      );
      const reservedProps = /* @__PURE__ */ new Set(["description", "label", "inputProps", "fieldType", "renderParent", "order"]);
      for (const [nestedKey, nestedValue] of Object.entries(nestedConfig)) {
        if (!reservedProps.has(nestedKey)) {
          config[nestedKey] = nestedValue;
        } else {
          console.warn(
            `Field "${key}" has a nested field named "${nestedKey}" which conflicts with a reserved FieldConfigItem property. The nested field's config will not be accessible at the parent level.`
          );
        }
      }
    }
    if (Object.keys(config).length > 0) {
      fieldConfig[key] = config;
    }
  }
  return fieldConfig;
}

exports.BUILTIN_FIELD_TYPES = BUILTIN_FIELD_TYPES;
exports.beautifyObjectName = beautifyObjectName;
exports.buildFieldConfigFromJsonSchema = buildFieldConfigFromJsonSchema;
exports.getBaseSchema = getBaseSchema;
exports.getBaseType = getBaseType;
exports.getDefaultValueInZodStack = getDefaultValueInZodStack;
exports.getDefaultValues = getDefaultValues;
exports.getObjectFormSchema = getObjectFormSchema;
exports.sortFieldsByOrder = sortFieldsByOrder;
exports.zodToHtmlInputProps = zodToHtmlInputProps;
