import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Info } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/tooltip.js";
import { FieldContext, useFieldContext } from "./field-context.js";
const MIN_H_CLASS = {
  sm: "min-h-field-sm",
  md: "min-h-field-md",
  lg: "min-h-field-lg"
};
const FIELD_HEIGHT_VAR = {
  sm: "var(--field-height-sm)",
  md: "var(--field-height-md)",
  lg: "var(--field-height-lg)"
};
const FIELD_TEXT_CLASS = "text-body";
function resolveSlotKind(node) {
  var _a;
  if (!React.isValidElement(node)) return "control";
  const displayName = (_a = node.type) == null ? void 0 : _a.displayName;
  if (displayName === "FieldLabel") return "label";
  if (displayName === "FieldDescription") return "description";
  if (displayName === "FieldError") return "error";
  return "control";
}
function detectControlLayout(controlNodes) {
  var _a;
  for (const node of controlNodes) {
    if (!React.isValidElement(node)) continue;
    const layout = (_a = node.type) == null ? void 0 : _a.fieldLayout;
    if (layout === "block") return "block";
  }
  return "inline";
}
const FieldGroupContext = React.createContext({});
const Field = React.forwardRef(
  ({
    id: idProp,
    mode = "edit",
    variant = "default",
    orientation = "vertical",
    size = "md",
    required = false,
    disabled: disabledProp = false,
    invalid = false,
    labelWidth,
    controlLayout: controlLayoutProp,
    className,
    style,
    children,
    ...props
  }, ref) => {
    const generatedId = React.useId();
    const id = idProp ?? generatedId;
    const labelId = `${id}-label`;
    const descriptionId = `${id}-description`;
    const errorId = `${id}-error`;
    const groupCtx = React.useContext(FieldGroupContext);
    const effectiveLabelWidth = labelWidth ?? groupCtx.horizontalLabelWidth;
    const disabled = disabledProp || mode === "disabled";
    const labelNodes = [];
    const controlNodes = [];
    const descriptionNodes = [];
    const errorNodes = [];
    React.Children.forEach(children, (child) => {
      const slot = resolveSlotKind(child);
      if (slot === "label") labelNodes.push(child);
      else if (slot === "description") descriptionNodes.push(child);
      else if (slot === "error") errorNodes.push(child);
      else controlNodes.push(child);
    });
    const controlLayout = controlLayoutProp ?? detectControlLayout(controlNodes);
    const contextValue = React.useMemo(
      () => ({
        id,
        labelId,
        descriptionId,
        errorId,
        mode,
        variant,
        disabled,
        required,
        invalid,
        size,
        orientation,
        controlLayout,
        hasFieldWrapper: true
      }),
      [id, labelId, descriptionId, errorId, mode, variant, disabled, required, invalid, size, orientation, controlLayout]
    );
    const controlArea = controlLayout === "block" ? /* @__PURE__ */ jsx(
      "div",
      {
        className: "flex flex-col items-start min-w-0",
        "data-field-slot": "control",
        "data-field-control-layout": "block",
        children: controlNodes
      }
    ) : /* @__PURE__ */ jsx(
      "div",
      {
        className: cn("flex items-center min-w-0", MIN_H_CLASS[size]),
        "data-field-slot": "control",
        "data-field-control-layout": "inline",
        children: controlNodes
      }
    );
    if (orientation === "horizontal") {
      return /* @__PURE__ */ jsx(FieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
        "div",
        {
          ref,
          className: cn("grid gap-x-3 items-start", className),
          style: {
            gridTemplateColumns: "var(--field-label-width, auto) minmax(0, 1fr)",
            ...effectiveLabelWidth !== void 0 ? { ["--field-label-width"]: effectiveLabelWidth } : void 0,
            ...style
          },
          "data-field-orientation": "horizontal",
          "data-field-mode": mode,
          "data-field-size": size,
          "data-field-disabled": disabled ? "" : void 0,
          "data-field-invalid": invalid ? "" : void 0,
          ...props,
          children: [
            labelNodes,
            /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
              controlArea,
              descriptionNodes,
              errorNodes
            ] })
          ]
        }
      ) });
    }
    return /* @__PURE__ */ jsx(FieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
      "div",
      {
        ref,
        className: cn("flex flex-col gap-1 min-w-0", className),
        style,
        "data-field-orientation": "vertical",
        "data-field-mode": mode,
        "data-field-size": size,
        "data-field-disabled": disabled ? "" : void 0,
        "data-field-invalid": invalid ? "" : void 0,
        ...props,
        children: [
          labelNodes,
          controlArea,
          descriptionNodes,
          errorNodes
        ]
      }
    ) });
  }
);
Field.displayName = "Field";
const FieldLabel = React.forwardRef(
  ({ className, required: requiredProp, info, htmlFor: htmlForProp, style, children, ...props }, ref) => {
    const ctx = useFieldContext();
    const required = requiredProp ?? (ctx == null ? void 0 : ctx.required) ?? false;
    const disabled = (ctx == null ? void 0 : ctx.disabled) ?? false;
    const htmlFor = htmlForProp ?? (ctx == null ? void 0 : ctx.id);
    const isHorizontal = (ctx == null ? void 0 : ctx.orientation) === "horizontal";
    const controlLayout = (ctx == null ? void 0 : ctx.controlLayout) ?? "inline";
    const size = (ctx == null ? void 0 : ctx.size) ?? "md";
    const horizontalInlineClass = isHorizontal && controlLayout === "inline" ? cn("flex flex-col justify-center", MIN_H_CLASS[size]) : void 0;
    const horizontalBlockStyle = isHorizontal && controlLayout === "block" ? { paddingTop: `calc((${FIELD_HEIGHT_VAR[size]} - 1lh) / 2)` } : void 0;
    return /* @__PURE__ */ jsx(
      "label",
      {
        ref,
        id: ctx == null ? void 0 : ctx.labelId,
        htmlFor,
        className: cn(
          FIELD_TEXT_CLASS,
          "font-normal select-none",
          disabled ? "text-fg-disabled" : "text-foreground",
          horizontalInlineClass,
          className
        ),
        style: { ...horizontalBlockStyle, ...style },
        "data-field-slot": "label",
        "data-field-disabled": disabled ? "" : void 0,
        "aria-disabled": disabled || void 0,
        ...props,
        children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
          /* @__PURE__ */ jsxs("span", { children: [
            required && /* @__PURE__ */ jsx(
              "span",
              {
                "aria-hidden": "true",
                className: disabled ? "text-fg-disabled" : "text-fg-muted",
                children: "*"
              }
            ),
            children
          ] }),
          info && !disabled && /* @__PURE__ */ jsxs(Tooltip, { children: [
            /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                "aria-label": info,
                className: "inline-flex items-center text-fg-muted hover:text-fg-secondary bg-transparent border-0 p-0 cursor-pointer",
                children: /* @__PURE__ */ jsx(Info, { size: 16, "aria-hidden": true })
              }
            ) }),
            /* @__PURE__ */ jsx(TooltipContent, { children: info })
          ] })
        ] })
      }
    );
  }
);
FieldLabel.displayName = "FieldLabel";
const FieldDescription = React.forwardRef(({ className, children, id: idProp, ...props }, ref) => {
  const ctx = useFieldContext();
  const disabled = (ctx == null ? void 0 : ctx.disabled) ?? false;
  return /* @__PURE__ */ jsx(
    "p",
    {
      ref,
      id: idProp ?? (ctx == null ? void 0 : ctx.descriptionId),
      className: cn(
        FIELD_TEXT_CLASS,
        disabled ? "text-fg-disabled" : "text-fg-secondary",
        className
      ),
      "data-field-slot": "description",
      ...props,
      children
    }
  );
});
FieldDescription.displayName = "FieldDescription";
const FieldError = React.forwardRef(({ className, children, id: idProp, ...props }, ref) => {
  const ctx = useFieldContext();
  if (children == null || children === false || children === "") return null;
  return /* @__PURE__ */ jsx(
    "p",
    {
      ref,
      id: idProp ?? (ctx == null ? void 0 : ctx.errorId),
      className: cn(FIELD_TEXT_CLASS, "text-error-text", className),
      "data-field-slot": "error",
      role: "alert",
      ...props,
      children
    }
  );
});
FieldError.displayName = "FieldError";
const FieldGroup = React.forwardRef(
  ({ className, gap = "normal", horizontalLabelWidth, ...props }, ref) => {
    const gapClass = gap === "compact" ? "gap-3" : gap === "loose" ? "gap-6" : "gap-4";
    const groupCtxValue = React.useMemo(
      () => ({ horizontalLabelWidth }),
      [horizontalLabelWidth]
    );
    return /* @__PURE__ */ jsx(FieldGroupContext.Provider, { value: groupCtxValue, children: /* @__PURE__ */ jsx(
      "div",
      {
        ref,
        className: cn("flex flex-col min-w-0", gapClass, className),
        "data-field-group": "",
        ...props
      }
    ) });
  }
);
FieldGroup.displayName = "FieldGroup";
const fieldMeta = {
  component: "Field",
  family: null,
  // non-family composite / overlay / layout
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: [],
    fg: ["text-error-text", "text-fg-disabled", "text-fg-muted", "text-fg-secondary", "text-foreground"],
    ring: []
  }
};
export {
  Field,
  FieldDescription,
  FieldError,
  FieldGroup,
  FieldLabel,
  fieldMeta
};
//# sourceMappingURL=field.js.map
