import { __name } from './chunk-CGILA3WO.mjs';
import consola from 'consola';
import { cn, isDev } from '@djangocfg/ui-core/lib';
import { ChevronDown, Plus, AlertCircle } from 'lucide-react';
import { useState, useMemo, useCallback, useRef } from 'react';
import { Label, Collapsible, CollapsibleTrigger, CollapsibleContent, Button, Alert, AlertTitle, AlertDescription, Input, Checkbox, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch, Slider } from '@djangocfg/ui-core/components';
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
import { jsx, jsxs } from 'react/jsx-runtime';
import { getUiOptions, getTemplate, getInputProps } from '@rjsf/utils';
import { useAppT } from '@djangocfg/i18n';

function FieldTemplate(props) {
  const {
    id,
    classNames,
    style,
    label,
    help,
    required,
    description,
    errors,
    children,
    displayLabel,
    hidden,
    rawErrors
  } = props;
  if (hidden) {
    return /* @__PURE__ */ jsx("div", { className: "hidden", children });
  }
  const hasError = rawErrors && rawErrors.length > 0;
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: cn("space-y-2", classNames),
      style,
      children: [
        displayLabel && label && /* @__PURE__ */ jsxs(Label, { htmlFor: id, className: cn(hasError && "text-destructive"), children: [
          label,
          required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", children: "*" })
        ] }),
        description && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: description }),
        /* @__PURE__ */ jsx("div", { children }),
        errors && /* @__PURE__ */ jsx("div", { className: "text-sm text-destructive", children: errors }),
        help && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: help })
      ]
    }
  );
}
__name(FieldTemplate, "FieldTemplate");
function ObjectFieldTemplate(props) {
  const {
    title,
    description,
    properties,
    required,
    uiSchema
  } = props;
  const isCollapsible = uiSchema?.["ui:collapsible"] === true;
  const defaultCollapsed = uiSchema?.["ui:collapsed"] === true;
  const gridCols = uiSchema?.["ui:grid"];
  const className = uiSchema?.["ui:className"];
  const [isOpen, setIsOpen] = useState(!defaultCollapsed);
  const isRoot = !title;
  const gridClass = gridCols ? `grid gap-4 grid-cols-${gridCols}` : "space-y-4";
  const content = /* @__PURE__ */ jsx("div", { className: cn(gridClass, className), children: properties.map((element) => /* @__PURE__ */ jsx("div", { className: "property-wrapper", children: element.content }, element.name)) });
  if (isRoot) {
    return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: content });
  }
  if (isCollapsible) {
    return /* @__PURE__ */ jsxs(Collapsible, { open: isOpen, onOpenChange: setIsOpen, className: "space-y-2", children: [
      /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex w-full items-center justify-between rounded-lg border bg-muted/50 px-4 py-3 text-left hover:bg-muted transition-colors", children: [
        /* @__PURE__ */ jsxs("div", { children: [
          /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold", children: [
            title,
            required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", children: "*" })
          ] }),
          description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: description })
        ] }),
        /* @__PURE__ */ jsx(
          ChevronDown,
          {
            className: cn(
              "h-4 w-4 text-muted-foreground transition-transform duration-200",
              isOpen && "rotate-180"
            )
          }
        )
      ] }),
      /* @__PURE__ */ jsx(CollapsibleContent, { className: "pl-1 pr-1 pt-2", children: content })
    ] });
  }
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    title && /* @__PURE__ */ jsxs("div", { className: "border-b pb-2", children: [
      /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold", children: [
        title,
        required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", children: "*" })
      ] }),
      description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: description })
    ] }),
    content
  ] });
}
__name(ObjectFieldTemplate, "ObjectFieldTemplate");
function ArrayFieldTemplate(props) {
  const {
    title,
    items,
    canAdd,
    onAddClick,
    required
  } = props;
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    title && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
      /* @__PURE__ */ jsxs("h3", { className: "text-lg font-semibold", children: [
        title,
        required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", children: "*" })
      ] }),
      canAdd && /* @__PURE__ */ jsxs(
        Button,
        {
          type: "button",
          variant: "outline",
          size: "sm",
          onClick: onAddClick,
          className: "gap-2",
          children: [
            /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
            "Add Item"
          ]
        }
      )
    ] }),
    /* @__PURE__ */ jsx("div", { className: "space-y-3", children: items }),
    items.length === 0 && /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-muted-foreground border-2 border-dashed rounded-md", children: [
      "No items added yet.",
      canAdd && /* @__PURE__ */ jsxs(
        Button,
        {
          type: "button",
          variant: "ghost",
          size: "sm",
          onClick: onAddClick,
          className: "mt-2 gap-2",
          children: [
            /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
            "Add First Item"
          ]
        }
      )
    ] })
  ] });
}
__name(ArrayFieldTemplate, "ArrayFieldTemplate");
function ArrayFieldItemTemplate(props) {
  const {
    children,
    className,
    buttonsProps,
    hasToolbar,
    registry,
    uiSchema
  } = props;
  const uiOptions = getUiOptions(uiSchema);
  const ArrayFieldItemButtonsTemplate = getTemplate(
    "ArrayFieldItemButtonsTemplate",
    registry,
    uiOptions
  );
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: cn(
        "flex gap-2 items-start p-4 rounded-md border bg-card",
        className
      ),
      children: [
        /* @__PURE__ */ jsx("div", { className: "flex-1", children }),
        hasToolbar && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx(ArrayFieldItemButtonsTemplate, { ...buttonsProps }) })
      ]
    }
  );
}
__name(ArrayFieldItemTemplate, "ArrayFieldItemTemplate");
function ErrorListTemplate(props) {
  const { errors } = props;
  if (!errors || errors.length === 0) {
    return null;
  }
  return /* @__PURE__ */ jsxs(Alert, { variant: "destructive", className: "mb-6", children: [
    /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
    /* @__PURE__ */ jsx(AlertTitle, { children: "Validation Errors" }),
    /* @__PURE__ */ jsx(AlertDescription, { children: /* @__PURE__ */ jsx("ul", { className: "list-disc list-inside space-y-1 mt-2", children: errors.map((error, index) => /* @__PURE__ */ jsx("li", { className: "text-sm", children: error.stack }, index)) }) })
  ] });
}
__name(ErrorListTemplate, "ErrorListTemplate");
function BaseInputTemplate(props) {
  const {
    id,
    type,
    value,
    readonly,
    disabled,
    autofocus,
    onBlur,
    onFocus,
    onChange,
    options,
    schema,
    rawErrors,
    placeholder
  } = props;
  const inputProps = useMemo(() => {
    return getInputProps(schema, type, options);
  }, [schema, type, options]);
  const safeValue = useMemo(() => {
    if (value === null || value === void 0) return "";
    return String(value);
  }, [value]);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const handleChange = useCallback((event) => {
    const val = event.target.value;
    if (val === "") {
      onChange(options?.emptyValue ?? "");
      return;
    }
    if (inputProps.type === "number" || schema.type === "number" || schema.type === "integer") {
      const num = Number(val);
      onChange(isNaN(num) ? val : num);
      return;
    }
    onChange(val);
  }, [onChange, inputProps.type, schema.type, options?.emptyValue]);
  const handleBlur = useCallback((event) => {
    onBlur(id, event.target.value);
  }, [id, onBlur]);
  const handleFocus = useCallback((event) => {
    onFocus(id, event.target.value);
  }, [id, onFocus]);
  const inputType = useMemo(() => {
    if (inputProps.type) return inputProps.type;
    if (schema.type === "number" || schema.type === "integer") return "number";
    return "text";
  }, [inputProps.type, schema.type]);
  return /* @__PURE__ */ jsx(
    Input,
    {
      id,
      type: inputType,
      value: safeValue,
      disabled,
      readOnly: readonly,
      autoFocus: autofocus,
      onChange: handleChange,
      onBlur: handleBlur,
      onFocus: handleFocus,
      placeholder,
      className: hasError ? "border-destructive" : "",
      step: inputProps.step,
      min: inputProps.min,
      max: inputProps.max
    }
  );
}
__name(BaseInputTemplate, "BaseInputTemplate");
function validateSchema(schema) {
  if (!schema || typeof schema !== "object") {
    if (isDev) {
      consola.error("[JsonSchemaForm] Invalid schema: must be an object", schema);
    }
    return null;
  }
  const hasValidStructure = schema.type || schema.properties || schema.$ref || schema.$schema;
  if (!hasValidStructure) {
    if (isDev) {
      consola.error("[JsonSchemaForm] Invalid schema: missing type, properties, $ref, or $schema", schema);
    }
    return null;
  }
  if (isDev) {
    consola.success("[JsonSchemaForm] Schema validated successfully:", {
      type: schema.type,
      title: schema.title,
      hasProperties: !!schema.properties,
      hasRequired: !!schema.required
    });
  }
  return schema;
}
__name(validateSchema, "validateSchema");
function normalizeFormData(formData, schema) {
  if (formData === null || formData === void 0) {
    return schema.type === "object" ? {} : schema.type === "array" ? [] : null;
  }
  const normalized = JSON.parse(JSON.stringify(formData));
  return removeUndefined(normalized);
}
__name(normalizeFormData, "normalizeFormData");
function removeUndefined(obj) {
  if (obj === null || obj === void 0) {
    return obj;
  }
  if (Array.isArray(obj)) {
    return obj.map(removeUndefined).filter((item) => item !== void 0);
  }
  if (typeof obj === "object") {
    const cleaned = {};
    for (const key in obj) {
      if (obj[key] !== void 0) {
        cleaned[key] = removeUndefined(obj[key]);
      }
    }
    return cleaned;
  }
  return obj;
}
__name(removeUndefined, "removeUndefined");
function mergeDefaults(formData, schema) {
  if (!schema) return formData;
  const result = { ...formData };
  if (schema.type === "object" && schema.properties) {
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      const prop = propSchema;
      if (result[key] === void 0 && prop.default !== void 0) {
        result[key] = prop.default;
      }
      if (prop.type === "object" && result[key]) {
        result[key] = mergeDefaults(result[key], prop);
      }
    }
  }
  return result;
}
__name(mergeDefaults, "mergeDefaults");
function safeJsonParse(jsonString, fallback) {
  try {
    return JSON.parse(jsonString);
  } catch (error) {
    consola.error("[JsonSchemaForm] JSON parse error:", error);
    return fallback;
  }
}
__name(safeJsonParse, "safeJsonParse");
function safeJsonStringify(obj, pretty = true) {
  try {
    return JSON.stringify(obj, null, pretty ? 2 : 0);
  } catch (error) {
    consola.error("[JsonSchemaForm] JSON stringify error:", error);
    return "{}";
  }
}
__name(safeJsonStringify, "safeJsonStringify");
function hasRequiredFields(schema) {
  return Array.isArray(schema.required) && schema.required.length > 0;
}
__name(hasRequiredFields, "hasRequiredFields");
function getRequiredFields(schema, prefix = "") {
  const required = [];
  if (schema.required && Array.isArray(schema.required)) {
    required.push(...schema.required.map(
      (field) => prefix ? `${prefix}.${field}` : field
    ));
  }
  if (schema.type === "object" && schema.properties) {
    for (const [key, propSchema] of Object.entries(schema.properties)) {
      const prop = propSchema;
      const fieldPath = prefix ? `${prefix}.${key}` : key;
      required.push(...getRequiredFields(prop, fieldPath));
    }
  }
  return required;
}
__name(getRequiredFields, "getRequiredFields");
function validateRequiredFields(formData, schema) {
  const requiredFields = getRequiredFields(schema);
  const missing = [];
  for (const field of requiredFields) {
    const value = getNestedValue(formData, field);
    if (value === void 0 || value === null || value === "") {
      missing.push(field);
    }
  }
  return {
    valid: missing.length === 0,
    missing
  };
}
__name(validateRequiredFields, "validateRequiredFields");
function getNestedValue(obj, path) {
  return path.split(".").reduce((current, key) => current?.[key], obj);
}
__name(getNestedValue, "getNestedValue");
function TextWidget(props) {
  const {
    id,
    placeholder,
    required,
    disabled,
    readonly,
    autofocus,
    value,
    onChange,
    onBlur,
    onFocus,
    options,
    schema,
    rawErrors
  } = props;
  const config = useMemo(() => ({
    isTextarea: options?.widget === "textarea",
    rows: options?.rows || 3,
    emptyValue: options?.emptyValue
  }), [options]);
  const safeValue = useMemo(() => {
    if (value === null || value === void 0) return "";
    return String(value);
  }, [value]);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const handleChange = useCallback((event) => {
    const newValue = event.target.value;
    onChange(newValue === "" ? config.emptyValue : newValue);
  }, [onChange, config.emptyValue]);
  const handleBlur = useCallback((event) => {
    onBlur(id, event.target.value);
  }, [id, onBlur]);
  const handleFocus = useCallback((event) => {
    onFocus(id, event.target.value);
  }, [id, onFocus]);
  if (config.isTextarea) {
    return /* @__PURE__ */ jsx(
      "textarea",
      {
        id,
        className: `flex min-h-[80px] w-full rounded-md border ${hasError ? "border-destructive" : "border-input"} bg-transparent px-3 py-2 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,
        placeholder,
        disabled: disabled || readonly,
        readOnly: readonly,
        autoFocus: autofocus,
        value: safeValue,
        required,
        onChange: handleChange,
        onBlur: handleBlur,
        onFocus: handleFocus,
        rows: config.rows
      }
    );
  }
  return /* @__PURE__ */ jsx(
    Input,
    {
      id,
      type: "text",
      placeholder,
      disabled,
      readOnly: readonly,
      autoFocus: autofocus,
      value: safeValue,
      required,
      onChange: handleChange,
      onBlur: handleBlur,
      onFocus: handleFocus,
      className: hasError ? "border-destructive" : ""
    }
  );
}
__name(TextWidget, "TextWidget");
function NumberWidget(props) {
  const {
    id,
    placeholder,
    required,
    disabled,
    readonly,
    autofocus,
    value,
    onChange,
    onBlur,
    onFocus,
    options,
    schema,
    rawErrors
  } = props;
  const config = useMemo(() => ({
    isInteger: schema.type === "integer",
    step: schema.type === "integer" ? "1" : "any",
    min: schema.minimum,
    max: schema.maximum,
    emptyValue: options?.emptyValue
  }), [schema, options]);
  const safeValue = useMemo(() => {
    if (value === null || value === void 0 || value === "") return "";
    if (typeof value === "number" && !isNaN(value)) return value;
    return "";
  }, [value]);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const handleChange = useCallback((event) => {
    const newValue = event.target.value;
    if (newValue === "") {
      onChange(config.emptyValue);
    } else {
      const parsedValue = config.isInteger ? parseInt(newValue, 10) : parseFloat(newValue);
      onChange(isNaN(parsedValue) ? config.emptyValue : parsedValue);
    }
  }, [onChange, config]);
  const handleBlur = useCallback((event) => {
    onBlur(id, event.target.value);
  }, [id, onBlur]);
  const handleFocus = useCallback((event) => {
    onFocus(id, event.target.value);
  }, [id, onFocus]);
  return /* @__PURE__ */ jsx(
    Input,
    {
      id,
      type: "number",
      placeholder,
      disabled,
      readOnly: readonly,
      autoFocus: autofocus,
      value: safeValue,
      required,
      onChange: handleChange,
      onBlur: handleBlur,
      onFocus: handleFocus,
      step: config.step,
      min: config.min,
      max: config.max,
      className: hasError ? "border-destructive" : ""
    }
  );
}
__name(NumberWidget, "NumberWidget");
function CheckboxWidget(props) {
  const {
    id,
    value,
    disabled,
    readonly,
    autofocus,
    onChange,
    onBlur,
    onFocus
  } = props;
  const handleChange = /* @__PURE__ */ __name((checked) => {
    onChange(checked);
  }, "handleChange");
  return /* @__PURE__ */ jsx(
    Checkbox,
    {
      id,
      checked: value || false,
      disabled: disabled || readonly,
      autoFocus: autofocus,
      onCheckedChange: handleChange,
      onBlur: () => onBlur(id, value),
      onFocus: () => onFocus(id, value)
    }
  );
}
__name(CheckboxWidget, "CheckboxWidget");
function SelectWidget(props) {
  const {
    id,
    options,
    value,
    required,
    disabled,
    readonly,
    autofocus,
    onChange,
    onBlur,
    onFocus,
    placeholder,
    rawErrors
  } = props;
  const enumOptions = useMemo(() => {
    const opts = options?.enumOptions;
    if (!Array.isArray(opts)) return [];
    return opts.filter((opt) => opt && opt.value !== void 0);
  }, [options]);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const safeValue = useMemo(() => {
    if (value === null || value === void 0) return "";
    return String(value);
  }, [value]);
  const handleChange = useCallback((newValue) => {
    onChange(newValue);
    onBlur(id, newValue);
  }, [onChange, onBlur, id]);
  if (enumOptions.length === 0) {
    return /* @__PURE__ */ jsx(
      "input",
      {
        id,
        type: "text",
        value: safeValue,
        onChange: (e) => onChange(e.target.value),
        onBlur: (e) => onBlur(id, e.target.value),
        onFocus: (e) => onFocus(id, e.target.value),
        disabled: disabled || readonly,
        readOnly: readonly,
        className: `flex h-10 w-full rounded-md border ${hasError ? "border-destructive" : "border-input"} bg-transparent px-3 py-2 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,
        placeholder
      }
    );
  }
  return /* @__PURE__ */ jsxs(
    Select,
    {
      value: safeValue,
      onValueChange: handleChange,
      disabled: disabled || readonly,
      required,
      children: [
        /* @__PURE__ */ jsx(
          SelectTrigger,
          {
            id,
            className: hasError ? "border-destructive" : "",
            autoFocus: autofocus,
            onFocus: () => onFocus(id, value),
            children: /* @__PURE__ */ jsx(SelectValue, { placeholder: placeholder || "Select an option" })
          }
        ),
        /* @__PURE__ */ jsx(SelectContent, { children: enumOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: String(option.value), children: option.label || String(option.value) }, String(option.value))) })
      ]
    }
  );
}
__name(SelectWidget, "SelectWidget");
function SwitchWidget(props) {
  const {
    id,
    value,
    disabled,
    readonly,
    onChange,
    onBlur,
    onFocus
  } = props;
  const handleChange = /* @__PURE__ */ __name((checked) => {
    onChange(checked);
  }, "handleChange");
  return /* @__PURE__ */ jsx(
    Switch,
    {
      id,
      checked: value || false,
      disabled: disabled || readonly,
      onCheckedChange: handleChange,
      onBlur: () => onBlur(id, value),
      onFocus: () => onFocus(id, value)
    }
  );
}
__name(SwitchWidget, "SwitchWidget");
function ColorWidget(props) {
  const {
    id,
    placeholder,
    required,
    disabled,
    readonly,
    autofocus,
    value,
    onChange,
    onBlur,
    onFocus,
    options,
    rawErrors
  } = props;
  const t = useAppT();
  const pickColorLabel = useMemo(() => t("tools.color.pick"), [t]);
  const colorInputRef = useRef(null);
  const format = useMemo(() => {
    if (options?.format) return options.format;
    if (typeof value === "string" && value.startsWith("#")) return "hex";
    return "hsl";
  }, [options?.format, value]);
  const safeValue = useMemo(() => {
    if (value === null || value === void 0) return "";
    return String(value);
  }, [value]);
  const hslToCss = useCallback((hslValue) => {
    if (!hslValue) return "transparent";
    if (hslValue.startsWith("#")) return hslValue;
    if (hslValue.startsWith("hsl")) return hslValue;
    const parts = hslValue.split(" ");
    if (parts.length === 3) {
      return `hsl(${parts[0]}, ${parts[1]}, ${parts[2]})`;
    }
    return "transparent";
  }, []);
  const previewColor = useMemo(() => {
    return hslToCss(safeValue);
  }, [safeValue, hslToCss]);
  const hexToHsl = useCallback((hex) => {
    hex = hex.replace("#", "");
    const r = parseInt(hex.substring(0, 2), 16) / 255;
    const g = parseInt(hex.substring(2, 4), 16) / 255;
    const b = parseInt(hex.substring(4, 6), 16) / 255;
    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    let h = 0;
    let s = 0;
    const l = (max + min) / 2;
    if (max !== min) {
      const d = max - min;
      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
      switch (max) {
        case r:
          h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
          break;
        case g:
          h = ((b - r) / d + 2) / 6;
          break;
        case b:
          h = ((r - g) / d + 4) / 6;
          break;
      }
    }
    return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
  }, []);
  const hslToHex = useCallback((hslValue) => {
    if (!hslValue || hslValue.startsWith("#")) return hslValue || "#000000";
    const parts = hslValue.split(" ");
    if (parts.length !== 3) return "#000000";
    const h = parseInt(parts[0]) / 360;
    const s = parseInt(parts[1].replace("%", "")) / 100;
    const l = parseInt(parts[2].replace("%", "")) / 100;
    const hue2rgb = /* @__PURE__ */ __name((p, q, t2) => {
      if (t2 < 0) t2 += 1;
      if (t2 > 1) t2 -= 1;
      if (t2 < 1 / 6) return p + (q - p) * 6 * t2;
      if (t2 < 1 / 2) return q;
      if (t2 < 2 / 3) return p + (q - p) * (2 / 3 - t2) * 6;
      return p;
    }, "hue2rgb");
    let r, g, b;
    if (s === 0) {
      r = g = b = l;
    } else {
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      r = hue2rgb(p, q, h + 1 / 3);
      g = hue2rgb(p, q, h);
      b = hue2rgb(p, q, h - 1 / 3);
    }
    const toHex = /* @__PURE__ */ __name((x) => {
      const hex = Math.round(x * 255).toString(16);
      return hex.length === 1 ? "0" + hex : hex;
    }, "toHex");
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
  }, []);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const handleChange = useCallback((event) => {
    const newValue = event.target.value;
    onChange(newValue);
  }, [onChange]);
  const handleColorPickerChange = useCallback((event) => {
    const hexValue2 = event.target.value;
    if (format === "hsl") {
      onChange(hexToHsl(hexValue2));
    } else {
      onChange(hexValue2);
    }
  }, [onChange, format, hexToHsl]);
  const handleBlur = useCallback((event) => {
    onBlur(id, event.target.value);
  }, [id, onBlur]);
  const handleFocus = useCallback((event) => {
    onFocus(id, event.target.value);
  }, [id, onFocus]);
  const hexValue = useMemo(() => {
    if (format === "hex" || safeValue.startsWith("#")) {
      return safeValue || "#000000";
    }
    return hslToHex(safeValue);
  }, [safeValue, format, hslToHex]);
  const handleColorBoxClick = useCallback(() => {
    if (!disabled && !readonly) {
      colorInputRef.current?.click();
    }
  }, [disabled, readonly]);
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
    /* @__PURE__ */ jsxs("div", { className: "relative", children: [
      /* @__PURE__ */ jsx(
        "button",
        {
          type: "button",
          onClick: handleColorBoxClick,
          disabled: disabled || readonly,
          className: "h-10 w-10 shrink-0 rounded-md border-2 border-input cursor-pointer hover:border-ring focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
          style: { backgroundColor: previewColor },
          "aria-label": pickColorLabel
        }
      ),
      /* @__PURE__ */ jsx(
        "input",
        {
          ref: colorInputRef,
          type: "color",
          value: hexValue,
          onChange: handleColorPickerChange,
          className: "absolute inset-0 opacity-0 w-full h-full cursor-pointer",
          disabled: disabled || readonly,
          tabIndex: -1
        }
      )
    ] }),
    /* @__PURE__ */ jsx(
      Input,
      {
        id,
        type: "text",
        placeholder: placeholder || (format === "hsl" ? "217 91% 60%" : "#3b82f6"),
        disabled,
        readOnly: readonly,
        autoFocus: autofocus,
        value: safeValue,
        required,
        onChange: handleChange,
        onBlur: handleBlur,
        onFocus: handleFocus,
        className: `flex-1 font-mono text-sm ${hasError ? "border-destructive" : ""}`
      }
    )
  ] });
}
__name(ColorWidget, "ColorWidget");
function SliderWidget(props) {
  const {
    id,
    disabled,
    readonly,
    value,
    onChange,
    schema,
    options,
    rawErrors
  } = props;
  const config = useMemo(() => {
    const min = schema.minimum ?? options?.min ?? 0;
    const max = schema.maximum ?? options?.max ?? 100;
    const step = options?.step ?? (schema.type === "integer" ? 1 : 0.1);
    const unit = options?.unit;
    const showInput = options?.showInput !== false;
    return { min, max, step, unit, showInput };
  }, [schema, options]);
  const numericValue = useMemo(() => {
    if (value === null || value === void 0 || value === "") {
      return config.min;
    }
    if (typeof value === "number") {
      return value;
    }
    if (typeof value === "string") {
      const parsed = parseFloat(value);
      return isNaN(parsed) ? config.min : parsed;
    }
    return config.min;
  }, [value, config.min]);
  const hasError = useMemo(() => {
    return rawErrors && rawErrors.length > 0;
  }, [rawErrors]);
  const handleSliderChange = useCallback((values) => {
    const newValue = values[0];
    if (config.unit) {
      onChange(`${newValue}${config.unit}`);
    } else {
      onChange(newValue);
    }
  }, [onChange, config.unit]);
  const handleInputChange = useCallback((event) => {
    const inputValue = event.target.value;
    if (config.unit) {
      const cleanValue = inputValue.replace(config.unit, "").trim();
      const parsed = parseFloat(cleanValue);
      if (!isNaN(parsed)) {
        onChange(`${parsed}${config.unit}`);
      } else if (inputValue === "") {
        onChange(`${config.min}${config.unit}`);
      }
    } else {
      const parsed = parseFloat(inputValue);
      onChange(isNaN(parsed) ? config.min : parsed);
    }
  }, [onChange, config.unit, config.min]);
  const displayValue = useMemo(() => {
    if (config.unit) {
      return `${numericValue}${config.unit}`;
    }
    return String(numericValue);
  }, [numericValue, config.unit]);
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", hasError && "text-destructive"), children: [
    /* @__PURE__ */ jsx(
      Slider,
      {
        id,
        disabled: disabled || readonly,
        value: [numericValue],
        onValueChange: handleSliderChange,
        min: config.min,
        max: config.max,
        step: config.step,
        className: "flex-1"
      }
    ),
    config.showInput ? /* @__PURE__ */ jsx(
      Input,
      {
        type: "text",
        value: displayValue,
        onChange: handleInputChange,
        disabled,
        readOnly: readonly,
        className: cn(
          "w-20 text-center font-mono text-sm",
          hasError && "border-destructive"
        )
      }
    ) : /* @__PURE__ */ jsx("span", { className: "w-16 text-right font-mono text-sm text-muted-foreground", children: displayValue })
  ] });
}
__name(SliderWidget, "SliderWidget");
function JsonSchemaForm(props) {
  const {
    schema,
    uiSchema,
    formData,
    onSubmit,
    onChange,
    onError,
    showErrorList = "top",
    liveValidate = false,
    disabled = false,
    readonly = false,
    className,
    showSubmitButton = true,
    submitButtonText = "Submit",
    ...restProps
  } = props;
  const validatedSchema = useMemo(() => {
    if (isDev) {
      consola.info("[JsonSchemaForm] Validating schema...", schema);
    }
    const result = validateSchema(schema);
    if (!result && isDev) {
      consola.error("[JsonSchemaForm] Schema validation failed");
    }
    return result;
  }, [schema]);
  const normalizedFormData = useMemo(() => {
    if (!validatedSchema) {
      if (isDev) {
        consola.warn("[JsonSchemaForm] Cannot normalize formData - invalid schema");
      }
      return null;
    }
    if (isDev) {
      consola.info("[JsonSchemaForm] Normalizing formData...", formData);
    }
    const normalized = normalizeFormData(formData, validatedSchema);
    if (isDev) {
      consola.info("[JsonSchemaForm] Normalized formData:", normalized);
    }
    return normalized;
  }, [formData, validatedSchema]);
  const widgets = useMemo(() => ({
    // Standard widget names (PascalCase) - used by RJSF internally
    TextWidget,
    NumberWidget,
    CheckboxWidget,
    SelectWidget,
    SwitchWidget,
    ColorWidget,
    SliderWidget,
    // Lowercase aliases - for uiSchema 'ui:widget' references
    text: TextWidget,
    number: NumberWidget,
    checkbox: CheckboxWidget,
    select: SelectWidget,
    switch: SwitchWidget,
    color: ColorWidget,
    slider: SliderWidget,
    range: SliderWidget
    // alias
  }), []);
  const templates = useMemo(() => ({
    FieldTemplate,
    ObjectFieldTemplate,
    ArrayFieldTemplate,
    ArrayFieldItemTemplate,
    ErrorListTemplate,
    BaseInputTemplate
  }), []);
  const handleSubmit = useCallback((data) => {
    if (onSubmit) {
      const cleanData = {
        ...data,
        formData: normalizeFormData(data.formData, validatedSchema)
      };
      onSubmit(cleanData);
    }
  }, [onSubmit, validatedSchema]);
  const handleChange = useCallback((data) => {
    if (onChange) {
      onChange(data);
    }
  }, [onChange]);
  const handleError = useCallback((errors) => {
    if (onError) {
      onError(errors);
    }
  }, [onError]);
  if (!validatedSchema) {
    return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
      /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
      /* @__PURE__ */ jsx(AlertDescription, { children: "Invalid schema provided. Please check the schema format." })
    ] }) });
  }
  return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
    Form,
    {
      schema: validatedSchema,
      uiSchema,
      formData: normalizedFormData,
      validator,
      widgets,
      templates,
      onSubmit: handleSubmit,
      onChange: handleChange,
      onError: handleError,
      showErrorList,
      liveValidate,
      disabled,
      readonly,
      ...restProps,
      children: showSubmitButton && /* @__PURE__ */ jsx("div", { className: "mt-6 flex gap-2", children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled, children: submitButtonText }) })
    }
  ) });
}
__name(JsonSchemaForm, "JsonSchemaForm");

export { ArrayFieldItemTemplate, ArrayFieldTemplate, BaseInputTemplate, CheckboxWidget, ColorWidget, ErrorListTemplate, FieldTemplate, JsonSchemaForm, NumberWidget, ObjectFieldTemplate, SelectWidget, SliderWidget, SwitchWidget, TextWidget, getRequiredFields, hasRequiredFields, mergeDefaults, normalizeFormData, safeJsonParse, safeJsonStringify, validateRequiredFields, validateSchema };
//# sourceMappingURL=chunk-JUGQNNDC.mjs.map
//# sourceMappingURL=chunk-JUGQNNDC.mjs.map