import { z } from "zod";
import { mediaRefSchema } from "../../types/blocks.js";
function generateEntitySchemas(entityConfig, options = {}) {
  var _a;
  const {
    includeReadOnly = false,
    includeChildEntities = true,
    customValidation = {},
    strict = true
  } = options;
  generateBaseSchema(entityConfig, customValidation, strict);
  const createFields = entityConfig.fields.filter((field) => !field.api.readOnly || includeReadOnly).reduce((acc, field) => {
    const fieldSchema = generateFieldSchema(field, customValidation, strict);
    if (fieldSchema) {
      acc[field.name] = fieldSchema;
    }
    return acc;
  }, {});
  if (includeChildEntities && entityConfig.childEntities) {
    const childrenSchema = generateChildrenSchema(entityConfig.childEntities, strict);
    if (Object.keys(childrenSchema).length > 0) {
      createFields.children = z.object(childrenSchema).optional();
    }
  }
  if ((_a = entityConfig.builder) == null ? void 0 : _a.enabled) {
    createFields.blocks = z.union([
      z.array(z.object({
        id: z.string(),
        blockSlug: z.string(),
        props: z.record(z.string(), z.unknown()).optional()
      })),
      z.unknown()
      // Fallback for flexibility
    ]).optional();
  }
  const createSchema = z.object(createFields);
  const updateSchema = createSchema.partial();
  const responseFields = entityConfig.fields.reduce((acc, field) => {
    const fieldSchema = generateFieldSchema(field, customValidation, false);
    if (fieldSchema) {
      acc[field.name] = fieldSchema;
    }
    return acc;
  }, {});
  responseFields.id = z.string();
  responseFields.createdAt = z.string().datetime();
  responseFields.updatedAt = z.string().datetime();
  let childSchemas;
  if (includeChildEntities && entityConfig.childEntities) {
    childSchemas = {};
    Object.entries(entityConfig.childEntities).forEach(([childName, childConfig]) => {
      childSchemas[childName] = generateChildEntitySchema(childConfig, false);
      responseFields[childName] = z.array(childSchemas[childName]).optional();
    });
    responseFields.children = z.record(z.string(), z.array(z.unknown())).optional();
  }
  const responseSchema = z.object(responseFields);
  const listSchema = z.object({
    data: z.array(responseSchema),
    meta: z.object({
      total: z.number(),
      page: z.number(),
      limit: z.number(),
      hasMore: z.boolean()
    }).optional(),
    children: z.record(z.string(), z.record(z.string(), z.array(z.unknown()))).optional()
  });
  return {
    create: createSchema,
    update: updateSchema,
    response: responseSchema,
    list: listSchema,
    childSchemas
  };
}
function generateBaseSchema(entityConfig, customValidation, strict) {
  const fields = entityConfig.fields.reduce((acc, field) => {
    const fieldSchema = generateFieldSchema(field, customValidation, strict);
    if (fieldSchema) {
      acc[field.name] = fieldSchema;
    }
    return acc;
  }, {});
  return z.object(fields);
}
function generateFieldSchema(field, customValidation, strict = true) {
  if (customValidation[field.name]) {
    return field.required ? customValidation[field.name] : customValidation[field.name].optional();
  }
  let schema;
  switch (field.type) {
    // Basic text types
    case "text":
    case "textarea":
      schema = z.union([
        z.string(),
        z.number(),
        // Accept numbers and convert to string
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return field.defaultValue !== void 0 ? String(field.defaultValue) : null;
        }
        const strVal = typeof val === "number" ? String(val) : val;
        const trimmed = strict ? strVal.trim() : strVal;
        if (field.maxLength && trimmed.length > field.maxLength) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `${field.display.label} cannot exceed ${field.maxLength} characters`
          });
          return z.NEVER;
        }
        return trimmed;
      });
      break;
    case "email":
      schema = z.union([
        z.string(),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return null;
        }
        const emailVal = strict ? val.trim().toLowerCase() : val;
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(emailVal)) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `${field.display.label} must be a valid email address`
          });
          return z.NEVER;
        }
        return emailVal;
      });
      break;
    case "url":
      schema = z.union([
        z.string(),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return null;
        }
        const trimmedVal = strict ? val.trim() : val;
        let normalizedUrl = trimmedVal;
        if (!/^https?:\/\//i.test(trimmedVal)) {
          normalizedUrl = `https://${trimmedVal}`;
        }
        try {
          new URL(normalizedUrl);
          return normalizedUrl;
        } catch {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `${field.display.label} must be a valid URL`
          });
          return z.NEVER;
        }
      });
      break;
    case "phone":
      schema = z.union([
        z.string(),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return null;
        }
        const phoneVal = strict ? val.trim() : val;
        const phoneRegex = /^[\+]?[\d\s\-\(\)]{6,20}$/;
        if (!phoneRegex.test(phoneVal)) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `${field.display.label} must be a valid phone number`
          });
          return z.NEVER;
        }
        return phoneVal;
      });
      break;
    case "number":
    case "range":
      schema = z.union([
        z.number(),
        z.string().transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return null;
          }
          const num = Number(val);
          if (isNaN(num)) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid number`
            });
            return z.NEVER;
          }
          return num;
        }),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === void 0) return null;
        if (typeof val === "number") {
          if (field.min !== void 0 && val < field.min) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be at least ${field.min}`
            });
            return z.NEVER;
          }
          if (field.max !== void 0 && val > field.max) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be at most ${field.max}`
            });
            return z.NEVER;
          }
        }
        return val;
      });
      break;
    case "doublerange":
      schema = z.array(z.number()).length(2, {
        message: `${field.display.label} must be a range with exactly 2 numbers`
      });
      break;
    case "boolean":
      schema = z.boolean();
      break;
    case "date":
      schema = z.union([
        z.string().date(`${field.display.label} must be a valid date (YYYY-MM-DD)`),
        z.string().transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return null;
          }
          try {
            const date = new Date(val);
            if (isNaN(date.getTime())) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} must be a valid date`
              });
              return z.NEVER;
            }
            return date.toISOString().split("T")[0];
          } catch {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid date`
            });
            return z.NEVER;
          }
        }),
        z.null()
      ]);
      break;
    case "datetime":
      schema = z.union([
        z.string().datetime(`${field.display.label} must be a valid datetime (ISO 8601)`),
        z.string().transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return null;
          }
          if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(val)) {
            return `${val}:00.000Z`;
          }
          try {
            const date = new Date(val);
            if (isNaN(date.getTime())) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} must be a valid datetime`
              });
              return z.NEVER;
            }
            return date.toISOString();
          } catch {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid datetime`
            });
            return z.NEVER;
          }
        }),
        z.null(),
        z.undefined()
      ]).transform((val) => val === void 0 ? null : val);
      break;
    case "json":
      schema = z.unknown();
      if (strict) {
        schema = z.union([
          z.object({}).passthrough(),
          z.array(z.unknown()),
          z.string().transform((str, ctx) => {
            if (str === "" || str === null || str === void 0) {
              if (field.required) {
                ctx.addIssue({
                  code: z.ZodIssueCode.custom,
                  message: `${field.display.label} is required`
                });
                return z.NEVER;
              }
              return null;
            }
            try {
              return JSON.parse(str);
            } catch {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} must be valid JSON`
              });
              return z.NEVER;
            }
          }),
          z.literal(""),
          z.null(),
          z.undefined()
        ]).transform((val) => {
          if (val === "" || val === null || val === void 0) {
            return null;
          }
          return val;
        });
      }
      break;
    // Selection types
    case "select":
    case "radio":
    case "buttongroup":
    case "combobox":
      if (field.options && field.options.length > 0) {
        const values = field.options.map((opt) => opt.value);
        schema = z.union([
          z.enum(values, {
            message: `${field.display.label} must be one of: ${values.join(", ")}`
          }),
          z.number(),
          // Accept numbers and convert to string
          z.literal(""),
          z.null(),
          z.undefined()
        ]).transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return null;
          }
          const strVal = typeof val === "number" ? String(val) : val;
          if (!values.includes(strVal)) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be one of: ${values.join(", ")}`
            });
            return z.NEVER;
          }
          return strVal;
        });
      } else {
        schema = z.string();
      }
      break;
    case "multiselect":
      if (field.options && field.options.length > 0) {
        const values = field.options.map((opt) => opt.value);
        schema = z.union([
          z.array(z.enum(values)),
          z.literal(""),
          z.null(),
          z.undefined()
        ]).transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return [];
          }
          return Array.isArray(val) ? val : [];
        });
      } else {
        schema = z.union([
          z.array(z.string()),
          z.literal(""),
          z.null(),
          z.undefined()
        ]).transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            if (field.required) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: `${field.display.label} is required`
              });
              return z.NEVER;
            }
            return [];
          }
          return Array.isArray(val) ? val : [];
        });
      }
      break;
    case "tags":
      schema = z.union([
        z.array(z.string()),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return [];
        }
        return Array.isArray(val) ? val : [];
      });
      break;
    // Specialized inputs
    case "rating":
      schema = z.number().min(0).max(5);
      break;
    // Location & data selectors
    case "timezone":
      schema = z.union([
        z.string(),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return null;
        }
        return val;
      });
      break;
    case "currency":
      schema = z.string().length(3, `${field.display.label} must be a valid 3-letter currency code`);
      break;
    case "country":
      schema = z.string().length(2, `${field.display.label} must be a valid 2-letter country code`);
      break;
    case "address":
      schema = z.object({
        street: z.string().optional(),
        city: z.string().optional(),
        state: z.string().optional(),
        zipCode: z.string().optional(),
        country: z.string().optional(),
        fullAddress: z.string().optional()
      });
      break;
    // Media types
    case "media-library":
      schema = mediaRefSchema.nullable();
      break;
    case "file":
    case "video":
    case "audio":
      schema = z.array(z.object({
        id: z.string(),
        name: z.string(),
        size: z.number(),
        url: z.string().url(),
        type: z.string().optional()
      }));
      break;
    case "image":
      schema = z.union([
        // Simple URL string
        z.string().url(),
        z.string().transform((val, ctx) => {
          if (val === "" || val === null || val === void 0) {
            return null;
          }
          if (val.startsWith("http") || val.startsWith("blob:") || val.startsWith("/")) {
            return val;
          }
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `${field.display.label} must be a valid image URL`
          });
          return z.NEVER;
        }),
        // Array of image objects (for multi-image)
        z.array(z.object({
          id: z.string(),
          name: z.string(),
          size: z.number(),
          url: z.string().url(),
          type: z.string().optional()
        })),
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val) => {
        if (val === "" || val === void 0) return null;
        return val;
      });
      break;
    // Relationship types
    case "relation":
      schema = z.union([
        z.string().min(1),
        // Simple ID string (non-empty)
        z.literal(""),
        // Empty string
        z.null(),
        z.undefined()
      ]).transform((val) => val === "" || val === void 0 ? null : val);
      break;
    case "relation-multi":
      schema = z.union([
        z.array(z.string().min(1)).transform((arr) => JSON.stringify(arr)),
        // Convert array to JSON string
        z.string().transform((str, ctx) => {
          if (str === "" || str === null || str === void 0) {
            return JSON.stringify([]);
          }
          try {
            const parsed = JSON.parse(str);
            if (Array.isArray(parsed)) {
              return str;
            }
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid JSON array`
            });
            return z.NEVER;
          } catch {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid JSON array`
            });
            return z.NEVER;
          }
        }),
        z.null().transform(() => JSON.stringify([])),
        z.undefined().transform(() => JSON.stringify([]))
      ]).default(JSON.stringify([]));
      break;
    case "relation-prop":
      schema = z.union([
        z.string().min(1),
        // Property value string (non-empty)
        z.literal(""),
        // Empty string
        z.null(),
        z.undefined()
      ]).transform((val) => val === "" || val === void 0 ? null : val);
      break;
    case "relation-prop-multi":
      schema = z.union([
        z.array(z.string().min(1)).transform((arr) => JSON.stringify(arr)),
        // Convert array to JSON string
        z.string().transform((str, ctx) => {
          if (str === "" || str === null || str === void 0) {
            return JSON.stringify([]);
          }
          try {
            const parsed = JSON.parse(str);
            if (Array.isArray(parsed)) {
              return str;
            }
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid JSON array`
            });
            return z.NEVER;
          } catch {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} must be a valid JSON array`
            });
            return z.NEVER;
          }
        }),
        z.null().transform(() => JSON.stringify([])),
        z.undefined().transform(() => JSON.stringify([]))
      ]).default(JSON.stringify([]));
      break;
    case "user":
      schema = z.union([
        // String user ID (primary format for database storage)
        z.string().min(1),
        // Legacy: array of user objects (kept for backward compatibility)
        z.array(z.object({
          id: z.union([z.string(), z.number()]),
          firstName: z.string().optional(),
          lastName: z.string().optional(),
          email: z.string().optional(),
          avatar: z.union([z.string(), z.null()]).optional(),
          role: z.string().optional()
        })),
        // Empty values
        z.literal(""),
        z.null(),
        z.undefined()
      ]).transform((val, ctx) => {
        if (val === "" || val === null || val === void 0 || Array.isArray(val) && val.length === 0) {
          if (field.required) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `${field.display.label} is required`
            });
            return z.NEVER;
          }
          return null;
        }
        if (Array.isArray(val) && val.length > 0) {
          const firstUser = val[0];
          if (typeof firstUser === "object" && firstUser.id) {
            return String(firstUser.id);
          }
        }
        return val;
      });
      break;
    // Text editors
    case "markdown":
    case "richtext":
    case "code":
      schema = z.string();
      if (strict) {
        schema = schema.trim();
      }
      break;
    default:
      console.warn(`Unknown field type: ${field.type} for field ${field.name}`);
      schema = z.unknown();
  }
  if (!field.required) {
    schema = schema.optional();
  }
  if (field.defaultValue !== void 0) {
    schema = schema.default(field.defaultValue);
  }
  return schema;
}
function generateChildrenSchema(childEntities, strict) {
  const childrenSchema = {};
  Object.entries(childEntities).forEach(([childName, childConfig]) => {
    childrenSchema[childName] = z.array(generateChildEntitySchema(childConfig, strict)).optional();
  });
  return childrenSchema;
}
function generateChildEntitySchema(childConfig, strict = true) {
  const fields = {};
  fields.id = z.string().optional();
  childConfig.fields.forEach((field) => {
    const entityField = {
      ...field,
      api: {
        searchable: false,
        sortable: true,
        readOnly: false
      },
      display: field.display || {
        label: field.name,
        description: `${field.name} field`,
        showInList: true,
        showInDetail: true,
        showInForm: true,
        order: 1
      }
    };
    const fieldSchema = generateFieldSchema(entityField, {}, strict);
    if (fieldSchema) {
      fields[field.name] = fieldSchema;
    }
  });
  return z.object(fields);
}
function generateTypeScriptTypes(entityConfig, schemas) {
  const entityName = pascalCase(entityConfig.slug);
  return `
// Auto-generated types for ${entityConfig.names.singular}

export type ${entityName}Create = z.infer<typeof schemas.create>
export type ${entityName}Update = z.infer<typeof schemas.update>
export type ${entityName}Response = z.infer<typeof schemas.response>
export type ${entityName}List = z.infer<typeof schemas.list>

${schemas.childSchemas ? Object.entries(schemas.childSchemas).map(
    ([childName]) => `export type ${entityName}${pascalCase(childName)} = z.infer<typeof schemas.childSchemas.${childName}>`
  ).join("\n") : ""}
`.trim();
}
function pascalCase(str) {
  return str.replace(/(?:^|[_-])(\w)/g, (_, char) => char.toUpperCase());
}
function validateEntityData(entityConfig, data, schemaType = "create", options = {}) {
  const schemas = generateEntitySchemas(entityConfig, options);
  const schema = schemas[schemaType];
  const result = schema.safeParse(data);
  if (result.success) {
    return { success: true, data: result.data };
  } else {
    return { success: false, errors: result.error };
  }
}
function generateSchemaDocumentation(entityConfig) {
  const { slug, names, fields } = entityConfig;
  let doc = `# ${names.singular} API Schema

`;
  doc += `## Entity: ${slug}

`;
  doc += `**Display Name**: ${names.singular}
`;
  doc += `**Plural**: ${names.plural}

`;
  doc += `## Fields

`;
  doc += `| Field | Type | Required | Description |
`;
  doc += `|-------|------|----------|-------------|
`;
  fields.forEach((field) => {
    const required = field.required ? "Yes" : "No";
    const description = field.display.description || field.display.label;
    doc += `| ${field.name} | ${field.type} | ${required} | ${description} |
`;
  });
  doc += `
## API Endpoints

`;
  doc += `- **GET** \`/api/v1/${slug}\` - List ${names.plural}
`;
  doc += `- **POST** \`/api/v1/${slug}\` - Create ${names.singular}
`;
  doc += `- **GET** \`/api/v1/${slug}/{id}\` - Get ${names.singular}
`;
  doc += `- **PATCH** \`/api/v1/${slug}/{id}\` - Update ${names.singular}
`;
  doc += `- **DELETE** \`/api/v1/${slug}/{id}\` - Delete ${names.singular}

`;
  if (entityConfig.childEntities) {
    doc += `## Child Entities

`;
    Object.entries(entityConfig.childEntities).forEach(([childName, childConfig]) => {
      doc += `### ${childName}
`;
      doc += `**Table**: ${childConfig.table}
`;
      doc += `**Fields**: ${childConfig.fields.map((f) => f.name).join(", ")}

`;
    });
  }
  return doc;
}
const REQUIRED_BUILDER_FIELDS = ["title", "slug", "status"];
function validateBuilderEntityConfig(entityConfig) {
  var _a, _b, _c, _d, _e, _f, _g;
  const result = {
    valid: true,
    errors: [],
    warnings: []
  };
  if (!((_a = entityConfig.builder) == null ? void 0 : _a.enabled)) {
    return result;
  }
  const fieldNames = entityConfig.fields.map((f) => f.name);
  for (const requiredField of REQUIRED_BUILDER_FIELDS) {
    if (!fieldNames.includes(requiredField)) {
      result.valid = false;
      result.errors.push(
        `Entity "${entityConfig.slug}" has builder.enabled=true but is missing required field: "${requiredField}". Builder entities must have fields: ${REQUIRED_BUILDER_FIELDS.join(", ")}`
      );
    }
  }
  const statusField = entityConfig.fields.find((f) => f.name === "status");
  if (statusField && statusField.type !== "select" && statusField.type !== "text") {
    result.warnings.push(
      `Entity "${entityConfig.slug}" has status field with type "${statusField.type}". Recommended: "select" with options ["draft", "published", ...] for better UX.`
    );
  }
  if (entityConfig.builder.sidebarFields) {
    for (const sidebarField of entityConfig.builder.sidebarFields) {
      if (!fieldNames.includes(sidebarField)) {
        result.warnings.push(
          `Entity "${entityConfig.slug}" references sidebarField "${sidebarField}" which does not exist in fields[].`
        );
      }
    }
  }
  const basePath = ((_b = entityConfig.access) == null ? void 0 : _b.basePath) ?? ((_c = entityConfig.builder.public) == null ? void 0 : _c.basePath);
  if (basePath) {
    if (!basePath.startsWith("/")) {
      result.errors.push(
        `Entity "${entityConfig.slug}" has invalid basePath: "${basePath}". basePath must start with "/".`
      );
      result.valid = false;
    }
    if (((_d = entityConfig.access) == null ? void 0 : _d.basePath) && ((_e = entityConfig.builder.public) == null ? void 0 : _e.basePath)) {
      result.warnings.push(
        `Entity "${entityConfig.slug}" has basePath defined in both access.basePath and builder.public.basePath. Using access.basePath. builder.public.basePath is deprecated and will be removed in v2.0.`
      );
    } else if (((_f = entityConfig.builder.public) == null ? void 0 : _f.basePath) && !((_g = entityConfig.access) == null ? void 0 : _g.basePath)) {
      result.warnings.push(
        `Entity "${entityConfig.slug}" uses deprecated builder.public.basePath. Please migrate to access.basePath. builder.public.basePath will be removed in v2.0.`
      );
    }
  }
  return result;
}
function validateTaxonomiesConfig(entityConfig) {
  var _a;
  const result = {
    valid: true,
    errors: [],
    warnings: []
  };
  if (!((_a = entityConfig.taxonomies) == null ? void 0 : _a.enabled)) {
    return result;
  }
  if (!entityConfig.taxonomies.types || entityConfig.taxonomies.types.length === 0) {
    result.errors.push(
      `Entity "${entityConfig.slug}" has taxonomies.enabled=true but taxonomies.types is empty. At least one taxonomy type must be defined.`
    );
    result.valid = false;
    return result;
  }
  for (const taxonomyType of entityConfig.taxonomies.types) {
    if (!taxonomyType.type) {
      result.errors.push(
        `Entity "${entityConfig.slug}" has a taxonomy type with missing "type" property.`
      );
      result.valid = false;
    }
    if (!taxonomyType.field) {
      result.errors.push(
        `Entity "${entityConfig.slug}" has a taxonomy type with missing "field" property.`
      );
      result.valid = false;
    }
    if (taxonomyType.multiple === void 0) {
      result.warnings.push(
        `Entity "${entityConfig.slug}" taxonomy type "${taxonomyType.type}" has no "multiple" property. Defaulting to false.`
      );
    }
  }
  return result;
}
function getBuilderEntities(registry) {
  return Object.values(registry).filter(
    (entity) => {
      var _a;
      return ((_a = entity.builder) == null ? void 0 : _a.enabled) === true;
    }
  );
}
function getEntityBasePath(entity) {
  var _a, _b, _c;
  return ((_a = entity.access) == null ? void 0 : _a.basePath) ?? ((_c = (_b = entity.builder) == null ? void 0 : _b.public) == null ? void 0 : _c.basePath);
}
function matchPathToEntity(path, registry) {
  var _a;
  const builderEntities = getBuilderEntities(registry);
  const sortedEntities = builderEntities.filter((e) => getEntityBasePath(e)).sort((a, b) => {
    const aPath = getEntityBasePath(a) || "/";
    const bPath = getEntityBasePath(b) || "/";
    return bPath.length - aPath.length;
  });
  for (const entity of sortedEntities) {
    const basePath = getEntityBasePath(entity);
    if (path === basePath) {
      return { entity, slug: "", isArchive: true };
    }
    if (basePath === "/") {
      const pattern = ((_a = entity.access) == null ? void 0 : _a.allowNestedSlugs) ? /^\/(.+)$/ : /^\/([^/]+)$/;
      const match = path.match(pattern);
      if (match) {
        return { entity, slug: match[1] };
      }
    } else {
      const pattern = new RegExp(`^${basePath.replace(/\//g, "\\/")}\\/(.+)$`);
      const match = path.match(pattern);
      if (match) {
        return { entity, slug: match[1] };
      }
    }
  }
  return null;
}
export {
  generateEntitySchemas,
  generateSchemaDocumentation,
  generateTypeScriptTypes,
  getBuilderEntities,
  getEntityBasePath,
  matchPathToEntity,
  validateBuilderEntityConfig,
  validateEntityData,
  validateTaxonomiesConfig
};
