import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Pencil } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { EMPTY_DISPLAY, fieldDisplayTextClass, fieldWrapperStyles, bareInputStyles } from "../Field/field-wrapper.js";
import { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant } from "../Field/field-context.js";
import { ItemInlineAction } from "../../patterns/element-anatomy/item-anatomy.js";
function isValidUrl(value) {
  if (!value) return true;
  try {
    const url = new URL(value);
    return url.protocol === "http:" || url.protocol === "https:";
  } catch {
    return false;
  }
}
function formatHostname(url) {
  try {
    return new URL(url).hostname.replace(/^www\./, "");
  } catch {
    return url;
  }
}
function renderLinkAnchor(value, label) {
  const displayText = label || formatHostname(value);
  return /* @__PURE__ */ jsx(
    "a",
    {
      href: value,
      target: "_blank",
      rel: "noopener noreferrer",
      className: "block truncate min-w-0 text-primary hover:text-primary-hover hover:underline transition-colors",
      children: displayText
    }
  );
}
const LinkInput = React.forwardRef(
  ({
    mode: modeProp,
    variant: variantProp,
    error: errorProp = false,
    size: sizeProp,
    value,
    onChange,
    placeholder = "https://",
    className,
    disabled: disabledProp,
    label,
    showDisplayEndIcon = false,
    readOnly,
    id: idProp,
    "aria-describedby": ariaDescribedByProp,
    "aria-errormessage": ariaErrorMessageProp,
    ...props
  }, ref) => {
    const fieldCtx = useFieldContext();
    const size = useResolvedFieldSize(sizeProp);
    const disabled = useResolvedFieldDisabled(disabledProp);
    const resolvedMode = useResolvedFieldMode({ mode: modeProp, disabled, readOnly });
    const isEditable = resolvedMode === "edit";
    const resolvedVariant = useResolvedFieldVariant(variantProp);
    if (resolvedMode === "display") {
      if (!showDisplayEndIcon) {
        if (!value) return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "text-fg-muted block truncate"), children: EMPTY_DISPLAY });
        return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "block truncate"), children: renderLinkAnchor(value, label) });
      }
      return /* @__PURE__ */ jsx(
        "div",
        {
          className: cn(fieldWrapperStyles({ mode: "display", variant: resolvedVariant, size }), className),
          "data-field-mode": "display",
          children: /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0 truncate", children: value ? renderLinkAnchor(value, label) : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: EMPTY_DISPLAY }) })
        }
      );
    }
    const [editing, setEditing] = React.useState(false);
    const [localValue, setLocalValue] = React.useState(value ?? "");
    const [localError, setLocalError] = React.useState(false);
    const inputRef = React.useRef(null);
    React.useEffect(() => {
      if (!editing) setLocalValue(value ?? "");
    }, [value, editing]);
    const setRef = React.useCallback((el) => {
      inputRef.current = el;
      if (typeof ref === "function") ref(el);
      else if (ref) ref.current = el;
    }, [ref]);
    const hasValidValue = !!value && isValidUrl(value);
    const showLink = isEditable && hasValidValue && !editing && !localError;
    const error = errorProp || localError;
    const focusRafIdRef = React.useRef(0);
    React.useEffect(() => () => {
      if (focusRafIdRef.current) cancelAnimationFrame(focusRafIdRef.current);
    }, []);
    const handleEdit = () => {
      setEditing(true);
      if (focusRafIdRef.current) cancelAnimationFrame(focusRafIdRef.current);
      focusRafIdRef.current = requestAnimationFrame(() => {
        var _a;
        focusRafIdRef.current = 0;
        (_a = inputRef.current) == null ? void 0 : _a.focus();
      });
    };
    const handleBlur = () => {
      setEditing(false);
      const trimmed = localValue.trim();
      if (!trimmed) {
        setLocalError(false);
        onChange == null ? void 0 : onChange("");
        return;
      }
      if (isValidUrl(trimmed)) {
        setLocalError(false);
        onChange == null ? void 0 : onChange(trimmed);
      } else {
        setLocalError(true);
      }
    };
    const handleChange = (e) => {
      setLocalValue(e.target.value);
      if (localError) setLocalError(false);
    };
    const handleKeyDown = (e) => {
      var _a;
      if (e.key === "Enter") (_a = inputRef.current) == null ? void 0 : _a.blur();
      if (e.key === "Escape") {
        setLocalValue(value ?? "");
        setLocalError(false);
        setEditing(false);
      }
    };
    if (!isEditable) {
      const displayText = value ? label || formatHostname(value) : null;
      return /* @__PURE__ */ jsx(
        "div",
        {
          className: cn(fieldWrapperStyles({ mode: resolvedMode, variant: resolvedVariant, size }), className),
          "data-field-mode": resolvedMode,
          children: /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0 truncate", children: resolvedMode === "disabled" ? displayText ? /* @__PURE__ */ jsx("span", { className: "text-fg-disabled", children: displayText }) : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: EMPTY_DISPLAY }) : value ? renderLinkAnchor(value, label) : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: EMPTY_DISPLAY }) })
        }
      );
    }
    if (showLink) {
      return /* @__PURE__ */ jsxs(
        "div",
        {
          className: cn(fieldWrapperStyles({ mode: "edit", variant: resolvedVariant, size }), className),
          "data-field-mode": "edit",
          children: [
            /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0", children: value && renderLinkAnchor(value, label) }),
            /* @__PURE__ */ jsx(
              ItemInlineAction,
              {
                size: size ?? "md",
                action: { icon: Pencil, label: "編輯連結", onClick: handleEdit }
              }
            )
          ]
        }
      );
    }
    return /* @__PURE__ */ jsx(
      "div",
      {
        className: cn(
          fieldWrapperStyles({ mode: "edit", variant: resolvedVariant, size }),
          error && [
            "border-error hover:border-error-hover",
            "focus-within:border-error focus-within:hover:border-error"
          ],
          className
        ),
        "data-field-mode": "edit",
        "data-error": error ? "" : void 0,
        children: /* @__PURE__ */ jsx(
          "input",
          {
            ref: setRef,
            type: "url",
            id: idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
            value: localValue,
            onChange: handleChange,
            onBlur: handleBlur,
            onKeyDown: handleKeyDown,
            placeholder,
            "aria-invalid": error || (fieldCtx == null ? void 0 : fieldCtx.invalid) || void 0,
            "aria-required": (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
            "aria-describedby": ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
            "aria-errormessage": ariaErrorMessageProp ?? (error || (fieldCtx == null ? void 0 : fieldCtx.invalid) ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
            className: bareInputStyles,
            ...props
          }
        )
      }
    );
  }
);
LinkInput.displayName = "LinkInput";
const linkInputMeta = {
  component: "LinkInput",
  family: 4,
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: [],
    fg: ["text-fg-disabled", "text-fg-muted", "text-primary"],
    ring: []
  }
};
export {
  LinkInput,
  linkInputMeta
};
//# sourceMappingURL=link-input.js.map
