import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '../../accordion.mjs';
import { FormField } from '../../form.mjs';
import { useFormContext } from 'react-hook-form';
import * as z from 'zod';
import { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from '../config.mjs';
import { getBaseSchema, sortFieldsByOrder, getBaseType, beautifyObjectName, zodToHtmlInputProps } from '../helpers.mjs';
import AutoFormArray from './array.mjs';
import resolveDependencies from '../dependencies.mjs';

function DefaultParent({ children }) {
  return /* @__PURE__ */ jsx(Fragment, { children });
}
function AutoFormObject({
  schema,
  form,
  fieldConfig,
  path = [],
  dependencies = []
}) {
  const { watch } = useFormContext();
  if (!schema) {
    return null;
  }
  const { shape } = getBaseSchema(schema) || {};
  if (!shape) {
    return null;
  }
  const handleIfZodNumber = (item) => {
    const def = item._zod?.def;
    const defType = def?.type;
    const innerDefType = def?.innerType?._zod?.def?.type;
    const isZodNumber = defType === "number" || defType === "int" || defType === "float";
    const isInnerZodNumber = innerDefType === "number" || innerDefType === "int" || innerDefType === "float";
    if (isZodNumber && def) {
      def.coerce = true;
    } else if (isInnerZodNumber && def?.innerType?._zod?.def) {
      def.innerType._zod.def.coerce = true;
    }
    return item;
  };
  const sortedFieldKeys = sortFieldsByOrder(fieldConfig, Object.keys(shape));
  return /* @__PURE__ */ jsx(Accordion, { type: "multiple", className: "space-y-5 border-none", children: sortedFieldKeys.map((name) => {
    let item = shape[name];
    item = handleIfZodNumber(item);
    const zodBaseType = getBaseType(item);
    const itemName = beautifyObjectName(name);
    const key = [...path, name].join(".");
    const {
      isHidden,
      isDisabled,
      isRequired: isRequiredByDependency,
      overrideOptions
    } = resolveDependencies(dependencies, name, watch);
    if (isHidden) {
      return null;
    }
    if (zodBaseType === "ZodObject") {
      const objectFieldConfig = fieldConfig?.[name] ?? {};
      if (typeof objectFieldConfig.fieldType === "function") {
        const zodInputProps2 = zodToHtmlInputProps(item);
        let isRequired2 = isRequiredByDependency || zodInputProps2.required || false;
        if (objectFieldConfig.inputProps?.required !== void 0) {
          isRequired2 = objectFieldConfig.inputProps.required;
        }
        const CustomComponent = objectFieldConfig.fieldType;
        const ParentElement = objectFieldConfig.renderParent ?? DefaultParent;
        return /* @__PURE__ */ jsx(
          FormField,
          {
            control: form.control,
            name: key,
            render: ({ field }) => {
              const fieldProps = {
                ...zodInputProps2,
                ...field,
                ...objectFieldConfig.inputProps,
                disabled: objectFieldConfig.inputProps?.disabled || isDisabled,
                ref: void 0,
                value: field.value
              };
              return /* @__PURE__ */ jsx(ParentElement, { children: /* @__PURE__ */ jsx(
                CustomComponent,
                {
                  zodInputProps: zodInputProps2,
                  field,
                  fieldConfigItem: objectFieldConfig,
                  label: objectFieldConfig.label || itemName,
                  isRequired: isRequired2,
                  zodItem: item,
                  fieldProps
                }
              ) }, `${key}.parent`);
            }
          },
          key
        );
      }
      return /* @__PURE__ */ jsxs(AccordionItem, { value: name, className: "border-none", children: [
        /* @__PURE__ */ jsx(AccordionTrigger, { children: itemName }),
        /* @__PURE__ */ jsx(AccordionContent, { className: "p-2", children: /* @__PURE__ */ jsx(
          AutoFormObject,
          {
            schema: item,
            form,
            fieldConfig: fieldConfig?.[name] ?? {},
            path: [...path, name]
          }
        ) })
      ] }, key);
    }
    if (zodBaseType === "ZodArray") {
      const arrayFieldConfig = fieldConfig?.[name] ?? {};
      if (typeof arrayFieldConfig.fieldType === "function") {
        const zodInputProps2 = zodToHtmlInputProps(item);
        let isRequired2 = isRequiredByDependency || zodInputProps2.required || false;
        if (arrayFieldConfig.inputProps?.required !== void 0) {
          isRequired2 = arrayFieldConfig.inputProps.required;
        }
        const CustomComponent = arrayFieldConfig.fieldType;
        const ParentElement = arrayFieldConfig.renderParent ?? DefaultParent;
        return /* @__PURE__ */ jsx(
          FormField,
          {
            control: form.control,
            name: key,
            render: ({ field }) => {
              const fieldProps = {
                ...zodInputProps2,
                ...field,
                ...arrayFieldConfig.inputProps,
                disabled: arrayFieldConfig.inputProps?.disabled || isDisabled,
                ref: void 0,
                value: field.value
              };
              return /* @__PURE__ */ jsx(ParentElement, { children: /* @__PURE__ */ jsx(
                CustomComponent,
                {
                  zodInputProps: zodInputProps2,
                  field,
                  fieldConfigItem: arrayFieldConfig,
                  label: arrayFieldConfig.label || itemName,
                  isRequired: isRequired2,
                  zodItem: item,
                  fieldProps
                }
              ) }, `${key}.parent`);
            }
          },
          key
        );
      }
      return /* @__PURE__ */ jsx(
        AutoFormArray,
        {
          name,
          item,
          form,
          fieldConfig: arrayFieldConfig,
          path: [...path, name]
        },
        key
      );
    }
    const fieldConfigItem = fieldConfig?.[name] ?? {};
    const zodInputProps = zodToHtmlInputProps(item);
    let isRequired = isRequiredByDependency || zodInputProps.required || false;
    if (fieldConfigItem.inputProps?.required !== void 0) {
      isRequired = fieldConfigItem.inputProps.required;
    }
    if (overrideOptions) {
      item = z.enum(overrideOptions);
    }
    return /* @__PURE__ */ jsx(
      FormField,
      {
        control: form.control,
        name: key,
        render: ({ field }) => {
          const inputType = fieldConfigItem.fieldType ?? DEFAULT_ZOD_HANDLERS[zodBaseType] ?? "fallback";
          const InputComponent = typeof inputType === "function" ? inputType : INPUT_COMPONENTS[inputType];
          const ParentElement = fieldConfigItem.renderParent ?? DefaultParent;
          const defaultValue = fieldConfigItem.inputProps?.defaultValue;
          const value = field.value ?? defaultValue ?? "";
          const fieldProps = {
            ...zodToHtmlInputProps(item),
            ...field,
            ...fieldConfigItem.inputProps,
            disabled: fieldConfigItem.inputProps?.disabled || isDisabled,
            ref: void 0,
            value
          };
          if (InputComponent === void 0) {
            return /* @__PURE__ */ jsx(Fragment, {});
          }
          return /* @__PURE__ */ jsx(ParentElement, { children: /* @__PURE__ */ jsx(
            InputComponent,
            {
              zodInputProps,
              field,
              fieldConfigItem,
              label: itemName,
              isRequired,
              zodItem: item,
              fieldProps,
              className: fieldProps.className
            }
          ) }, `${key}.parent`);
        }
      },
      key
    );
  }) });
}

export { AutoFormObject as default };
