"use client";
import * as React from 'react';
import { Fragment, useState, useCallback, useMemo } from 'react';
import { useForm, Form, Field } from '@page-speed/forms';
import { TextInput as TextInput$1 } from '@page-speed/forms/inputs';
import { Img } from '@page-speed/img';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { cva } from 'class-variance-authority';
import { jsx, jsxs } from 'react/jsx-runtime';
import { Slot } from '@radix-ui/react-slot';
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
import * as LabelPrimitive from '@radix-ui/react-label';
import { serializeForRails, deserializeErrors } from '@page-speed/forms/integration';

// components/blocks/resource-list/resource-list-hero-filter.tsx
var TextInput = TextInput$1;
function cn(...inputs) {
  return twMerge(clsx(inputs));
}
function normalizePhoneNumber(input) {
  const trimmed = input.trim();
  if (trimmed.toLowerCase().startsWith("tel:")) {
    return trimmed;
  }
  const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
  if (match) {
    const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
    const extension = match[3];
    const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
    const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
    return `tel:${withExtension}`;
  }
  const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
  return `tel:${cleaned}`;
}
function normalizeEmail(input) {
  const trimmed = input.trim();
  if (trimmed.toLowerCase().startsWith("mailto:")) {
    return trimmed;
  }
  return `mailto:${trimmed}`;
}
function isEmail(input) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(input.trim());
}
function isPhoneNumber(input) {
  const trimmed = input.trim();
  if (trimmed.toLowerCase().startsWith("tel:")) {
    return true;
  }
  const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
  return phoneRegex.test(trimmed);
}
function isInternalUrl(href) {
  if (typeof window === "undefined") {
    return href.startsWith("/") && !href.startsWith("//");
  }
  const trimmed = href.trim();
  if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
    return true;
  }
  try {
    const url = new URL(trimmed, window.location.href);
    const currentOrigin = window.location.origin;
    const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
    return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
  } catch {
    return false;
  }
}
function toRelativePath(href) {
  if (typeof window === "undefined") {
    return href;
  }
  const trimmed = href.trim();
  if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
    return trimmed;
  }
  try {
    const url = new URL(trimmed, window.location.href);
    const currentOrigin = window.location.origin;
    const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
    if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
      return url.pathname + url.search + url.hash;
    }
  } catch {
  }
  return trimmed;
}
function useNavigation({
  href,
  onClick
} = {}) {
  const linkType = React.useMemo(() => {
    if (!href || href.trim() === "") {
      return onClick ? "none" : "none";
    }
    const trimmed = href.trim();
    if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
      return "mailto";
    }
    if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
      return "tel";
    }
    if (isInternalUrl(trimmed)) {
      return "internal";
    }
    try {
      new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
      return "external";
    } catch {
      return "internal";
    }
  }, [href, onClick]);
  const normalizedHref = React.useMemo(() => {
    if (!href || href.trim() === "") {
      return void 0;
    }
    const trimmed = href.trim();
    switch (linkType) {
      case "tel":
        return normalizePhoneNumber(trimmed);
      case "mailto":
        return normalizeEmail(trimmed);
      case "internal":
        return toRelativePath(trimmed);
      case "external":
        return trimmed;
      default:
        return trimmed;
    }
  }, [href, linkType]);
  const target = React.useMemo(() => {
    switch (linkType) {
      case "external":
        return "_blank";
      case "internal":
        return "_self";
      case "mailto":
      case "tel":
        return void 0;
      default:
        return void 0;
    }
  }, [linkType]);
  const rel = React.useMemo(() => {
    if (linkType === "external") {
      return "noopener noreferrer";
    }
    return void 0;
  }, [linkType]);
  const isExternal = linkType === "external";
  const isInternal = linkType === "internal";
  const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
  const handleClick = React.useCallback(
    (event) => {
      if (onClick) {
        try {
          onClick(event);
        } catch (error) {
          console.error("Error in user onClick handler:", error);
        }
      }
      if (event.defaultPrevented) {
        return;
      }
      if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
      !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
        if (typeof window !== "undefined") {
          const handler = window.__opensiteNavigationHandler;
          if (typeof handler === "function") {
            try {
              const handled = handler(normalizedHref, event.nativeEvent || event);
              if (handled !== false) {
                event.preventDefault();
              }
            } catch (error) {
              console.error("Error in navigation handler:", error);
            }
          }
        }
      }
    },
    [onClick, shouldUseRouter, normalizedHref]
  );
  return {
    linkType,
    normalizedHref,
    target,
    rel,
    isExternal,
    isInternal,
    shouldUseRouter,
    handleClick
  };
}
var baseStyles = [
  // Layout
  "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
  // Typography - using CSS variables with sensible defaults
  "font-[var(--button-font-family,inherit)]",
  "font-[var(--button-font-weight,500)]",
  "tracking-[var(--button-letter-spacing,0)]",
  "leading-[var(--button-line-height,1.25)]",
  "[text-transform:var(--button-text-transform,none)]",
  "text-sm",
  // Border radius
  "rounded-[var(--button-radius,var(--radius,0.375rem))]",
  // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
  "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
  // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
  "[box-shadow:var(--button-shadow,none)]",
  "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
  // Disabled state
  "disabled:pointer-events-none disabled:opacity-50",
  // SVG handling
  "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
  // Focus styles
  "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
  // Invalid state
  "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
].join(" ");
var buttonVariants = cva(baseStyles, {
  variants: {
    variant: {
      // Default (Primary) variant - full customization
      default: [
        "bg-[var(--button-default-bg,hsl(var(--primary)))]",
        "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
        "border-[length:var(--button-default-border-width,0px)]",
        "border-[color:var(--button-default-border,transparent)]",
        "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
        "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
        "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
        "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
        "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
      ].join(" "),
      // Destructive variant - full customization
      destructive: [
        "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
        "text-[var(--button-destructive-fg,white)]",
        "border-[length:var(--button-destructive-border-width,0px)]",
        "border-[color:var(--button-destructive-border,transparent)]",
        "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
        "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
        "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
        "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
        "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
        "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
        "dark:bg-destructive/60"
      ].join(" "),
      // Outline variant - full customization with proper border handling
      outline: [
        "bg-[var(--button-outline-bg,hsl(var(--background)))]",
        "text-[var(--button-outline-fg,inherit)]",
        "border-[length:var(--button-outline-border-width,1px)]",
        "border-[color:var(--button-outline-border,hsl(var(--border)))]",
        "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
        "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
        "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
        "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
        "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
        "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
      ].join(" "),
      // Secondary variant - full customization
      secondary: [
        "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
        "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
        "border-[length:var(--button-secondary-border-width,0px)]",
        "border-[color:var(--button-secondary-border,transparent)]",
        "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
        "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
        "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
        "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
        "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
      ].join(" "),
      // Ghost variant - full customization
      ghost: [
        "bg-[var(--button-ghost-bg,transparent)]",
        "text-[var(--button-ghost-fg,inherit)]",
        "border-[length:var(--button-ghost-border-width,0px)]",
        "border-[color:var(--button-ghost-border,transparent)]",
        "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
        "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
        "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
        "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
        "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
        "dark:hover:bg-accent/50"
      ].join(" "),
      // Link variant - full customization
      link: [
        "bg-[var(--button-link-bg,transparent)]",
        "text-[var(--button-link-fg,hsl(var(--primary)))]",
        "border-[length:var(--button-link-border-width,0px)]",
        "border-[color:var(--button-link-border,transparent)]",
        "[box-shadow:var(--button-link-shadow,none)]",
        "hover:bg-[var(--button-link-hover-bg,transparent)]",
        "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
        "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
        "underline-offset-4 hover:underline"
      ].join(" ")
    },
    size: {
      default: [
        "h-[var(--button-height-md,2.25rem)]",
        "px-[var(--button-padding-x-md,1rem)]",
        "py-[var(--button-padding-y-md,0.5rem)]",
        "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
      ].join(" "),
      sm: [
        "h-[var(--button-height-sm,2rem)]",
        "px-[var(--button-padding-x-sm,0.75rem)]",
        "py-[var(--button-padding-y-sm,0.25rem)]",
        "gap-1.5",
        "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
      ].join(" "),
      md: [
        "h-[var(--button-height-md,2.25rem)]",
        "px-[var(--button-padding-x-md,1rem)]",
        "py-[var(--button-padding-y-md,0.5rem)]",
        "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
      ].join(" "),
      lg: [
        "h-[var(--button-height-lg,2.5rem)]",
        "px-[var(--button-padding-x-lg,1.5rem)]",
        "py-[var(--button-padding-y-lg,0.5rem)]",
        "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
      ].join(" "),
      icon: "size-[var(--button-height-md,2.25rem)]",
      "icon-sm": "size-[var(--button-height-sm,2rem)]",
      "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
    }
  },
  defaultVariants: {
    variant: "default",
    size: "default"
  }
});
var Pressable = React.forwardRef(
  ({
    children,
    className,
    href,
    onClick,
    variant,
    size,
    asButton = false,
    fallbackComponentType = "span",
    componentType,
    "aria-label": ariaLabel,
    "aria-describedby": ariaDescribedby,
    id,
    ...props
  }, ref) => {
    const navigation = useNavigation({ href, onClick });
    const {
      normalizedHref,
      target,
      rel,
      linkType,
      isInternal,
      handleClick
    } = navigation;
    const shouldRenderLink = normalizedHref && linkType !== "none";
    const shouldRenderButton = !shouldRenderLink && onClick;
    const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
    const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
    const shouldApplyButtonStyles = asButton || variant || size;
    const combinedClassName = cn(
      shouldApplyButtonStyles && buttonVariants({ variant, size }),
      className
    );
    const dataProps = Object.fromEntries(
      Object.entries(props).filter(([key]) => key.startsWith("data-"))
    );
    const buttonDataAttributes = shouldApplyButtonStyles ? {
      "data-slot": "button",
      "data-variant": variant ?? "default",
      "data-size": size ?? "default"
    } : {};
    const commonProps = {
      className: combinedClassName,
      onClick: handleClick,
      "aria-label": ariaLabel,
      "aria-describedby": ariaDescribedby,
      id,
      ...dataProps,
      ...buttonDataAttributes
    };
    if (finalComponentType === "a" && shouldRenderLink) {
      return /* @__PURE__ */ jsx(
        "a",
        {
          ref,
          href: normalizedHref,
          target,
          rel,
          ...commonProps,
          ...props,
          children
        }
      );
    }
    if (finalComponentType === "button") {
      return /* @__PURE__ */ jsx(
        "button",
        {
          ref,
          type: props.type || "button",
          ...commonProps,
          ...props,
          children
        }
      );
    }
    if (finalComponentType === "div") {
      return /* @__PURE__ */ jsx(
        "div",
        {
          ref,
          ...commonProps,
          children
        }
      );
    }
    return /* @__PURE__ */ jsx(
      "span",
      {
        ref,
        ...commonProps,
        children
      }
    );
  }
);
Pressable.displayName = "Pressable";
var svgCache = /* @__PURE__ */ new Map();
function DynamicIcon({
  name,
  size = 28,
  color,
  className,
  alt
}) {
  const [svgContent, setSvgContent] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const { url, iconName } = React.useMemo(() => {
    const separator = name.includes("/") ? "/" : ":";
    const [prefix, iconName2] = name.split(separator);
    const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
    return {
      url: baseUrl,
      iconName: iconName2
    };
  }, [name, size]);
  React.useEffect(() => {
    let isMounted = true;
    const fetchSvg = async () => {
      const cached = svgCache.get(url);
      if (cached) {
        if (isMounted) {
          setSvgContent(cached);
          setIsLoading(false);
        }
        return;
      }
      try {
        setIsLoading(true);
        setError(null);
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`Failed to fetch icon: ${response.status}`);
        }
        let svg = await response.text();
        svg = processSvgForCurrentColor(svg);
        svgCache.set(url, svg);
        if (isMounted) {
          setSvgContent(svg);
          setIsLoading(false);
        }
      } catch (err) {
        if (isMounted) {
          setError(err instanceof Error ? err.message : "Failed to load icon");
          setIsLoading(false);
        }
      }
    };
    fetchSvg();
    return () => {
      isMounted = false;
    };
  }, [url]);
  if (isLoading) {
    return /* @__PURE__ */ jsx(
      "span",
      {
        className: cn("inline-block", className),
        style: { width: size, height: size },
        "aria-hidden": "true"
      }
    );
  }
  if (error || !svgContent) {
    return /* @__PURE__ */ jsx(
      "span",
      {
        className: cn("inline-block", className),
        style: { width: size, height: size },
        role: "img",
        "aria-label": alt || iconName
      }
    );
  }
  return /* @__PURE__ */ jsx(
    "span",
    {
      className: cn("inline-flex items-center justify-center", className),
      style: {
        width: size,
        height: size,
        color: color || "inherit"
      },
      role: "img",
      "aria-label": alt || iconName,
      dangerouslySetInnerHTML: { __html: svgContent }
    }
  );
}
function processSvgForCurrentColor(svg) {
  let processed = svg;
  processed = processed.replace(
    /stroke=["'](#000000|#000|black)["']/gi,
    'stroke="currentColor"'
  );
  processed = processed.replace(
    /fill=["'](#000000|#000|black)["']/gi,
    'fill="currentColor"'
  );
  return processed;
}
var badgeVariants = cva(
  "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
        secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
        destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
        outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
      }
    },
    defaultVariants: {
      variant: "default"
    }
  }
);
function Badge({
  className,
  variant,
  asChild = false,
  ...props
}) {
  const Comp = asChild ? Slot : "span";
  return /* @__PURE__ */ jsx(
    Comp,
    {
      "data-slot": "badge",
      className: cn(badgeVariants({ variant }), className),
      ...props
    }
  );
}
function Card({ className, ...props }) {
  return /* @__PURE__ */ jsx(
    "div",
    {
      "data-slot": "card",
      className: cn(
        "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
        className
      ),
      ...props
    }
  );
}
function CardContent({ className, ...props }) {
  return /* @__PURE__ */ jsx(
    "div",
    {
      "data-slot": "card-content",
      className: cn("px-6", className),
      ...props
    }
  );
}
function AspectRatio({
  ...props
}) {
  return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
}
function Checkbox({
  className,
  ...props
}) {
  return /* @__PURE__ */ jsx(
    CheckboxPrimitive.Root,
    {
      "data-slot": "checkbox",
      className: cn(
        "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
        className
      ),
      ...props,
      children: /* @__PURE__ */ jsx(
        CheckboxPrimitive.Indicator,
        {
          "data-slot": "checkbox-indicator",
          className: "grid place-content-center text-current transition-none",
          children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/check", size: 14 })
        }
      )
    }
  );
}
function Label({
  className,
  ...props
}) {
  return /* @__PURE__ */ jsx(
    LabelPrimitive.Root,
    {
      "data-slot": "label",
      className: cn(
        "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
        className
      ),
      ...props
    }
  );
}
function Breadcrumb({ ...props }) {
  return /* @__PURE__ */ jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
}
function BreadcrumbList({ className, ...props }) {
  return /* @__PURE__ */ jsx(
    "ol",
    {
      "data-slot": "breadcrumb-list",
      className: cn(
        "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
        className
      ),
      ...props
    }
  );
}
function BreadcrumbItem({ className, ...props }) {
  return /* @__PURE__ */ jsx(
    "li",
    {
      "data-slot": "breadcrumb-item",
      className: cn("inline-flex items-center gap-1.5", className),
      ...props
    }
  );
}
function BreadcrumbLink({
  asChild,
  className,
  ...props
}) {
  const Comp = asChild ? Slot : "a";
  return /* @__PURE__ */ jsx(
    Comp,
    {
      "data-slot": "breadcrumb-link",
      className: cn("hover:text-foreground transition-colors", className),
      ...props
    }
  );
}
function BreadcrumbSeparator({
  children,
  className,
  ...props
}) {
  return /* @__PURE__ */ jsx(
    "li",
    {
      "data-slot": "breadcrumb-separator",
      role: "presentation",
      "aria-hidden": "true",
      className: cn("[&>svg]:size-3.5", className),
      ...props,
      children: children ?? /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 14 })
    }
  );
}
var PageSpeedFormSubmissionError = class extends Error {
  constructor(message, options = {}) {
    super(message);
    this.name = "PageSpeedFormSubmissionError";
    this.formErrors = options.formErrors;
    this.status = options.status;
  }
};
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
function isValidEmail(value) {
  return EMAIL_REGEX.test(value);
}
function buildUrlWithParams(endpoint, values) {
  const base = typeof window === "undefined" ? "http://localhost" : window.location.origin;
  const url = new URL(endpoint, base);
  Object.entries(values).forEach(([key, value]) => {
    if (value === void 0 || value === null) {
      return;
    }
    if (Array.isArray(value)) {
      value.forEach((item) => {
        if (item !== void 0 && item !== null) {
          url.searchParams.append(key, String(item));
        }
      });
      return;
    }
    url.searchParams.set(key, String(value));
  });
  return url.toString();
}
function normalizeMethod(method) {
  return (method || "post").toUpperCase();
}
function resolveFormat(config) {
  if (config?.format) {
    return config.format;
  }
  return config?.apiKey ? "rails" : "json";
}
function mergeValues(values, config) {
  return {
    ...config?.values ?? {},
    ...values
  };
}
async function submitPageSpeedForm(values, config) {
  if (!config?.endpoint) {
    return null;
  }
  const payload = mergeValues(values, config);
  const method = normalizeMethod(config.method);
  const format = resolveFormat(config);
  const headers = { ...config.headers ?? {} };
  if (format === "rails") {
    if (!config.apiKey) {
      throw new PageSpeedFormSubmissionError(
        "Missing apiKey for Rails form submission."
      );
    }
    const railsConfig = {
      apiKey: config.apiKey,
      contactCategoryToken: config.contactCategoryToken,
      locationId: config.locationId,
      websiteId: config.websiteId,
      websiteFormAssignmentId: config.websiteFormAssignmentId,
      visitorIpAddress: config.visitorIpAddress
    };
    const serialized = serializeForRails(payload, railsConfig);
    if (serialized.contact.contact_form_upload_tokens) {
      serialized.contact.contact_form_upload_tokens = serialized.contact.contact_form_upload_tokens.map((token) => token.replace(/^upload_/, ""));
    }
    headers["Content-Type"] ?? (headers["Content-Type"] = "application/json");
    const response2 = await fetch(config.endpoint, {
      method,
      headers,
      body: JSON.stringify(serialized)
    });
    const data2 = await response2.json().catch(() => null);
    if (!response2.ok || data2 && data2.errors) {
      const errorResponse = {
        errors: data2?.errors ?? { base: ["Form submission failed"] },
        status: data2?.status ?? response2.status
      };
      const formErrors = deserializeErrors(errorResponse);
      throw new PageSpeedFormSubmissionError("Form submission failed.", {
        formErrors,
        status: errorResponse.status
      });
    }
    return data2;
  }
  if (method === "GET") {
    const url = buildUrlWithParams(config.endpoint, payload);
    const response2 = await fetch(url, { method, headers });
    const data2 = await response2.json().catch(() => null);
    if (!response2.ok) {
      throw new PageSpeedFormSubmissionError(
        data2?.message || "Form submission failed.",
        { status: response2.status }
      );
    }
    return data2;
  }
  headers["Content-Type"] ?? (headers["Content-Type"] = "application/json");
  const response = await fetch(config.endpoint, {
    method,
    headers,
    body: JSON.stringify(payload)
  });
  const data = await response.json().catch(() => null);
  if (!response.ok) {
    throw new PageSpeedFormSubmissionError(
      data?.message || "Form submission failed.",
      { status: response.status }
    );
  }
  return data;
}

// lib/patternSvgs.ts
var patternSvgs = {
  dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl"};
var FilterForm = ({ categories, onCategoryChange }) => {
  const [selectedItems, setSelectedItems] = useState(["all"]);
  const handleCheckboxChange = useCallback(
    (checked, categoryValue) => {
      let updatedValues = checked ? [...selectedItems, categoryValue] : selectedItems.filter((value) => value !== categoryValue);
      if (updatedValues.length === 0) {
        setSelectedItems(["all"]);
        onCategoryChange(["all"]);
        return;
      }
      if (updatedValues.includes("all") && categoryValue !== "all") {
        updatedValues = updatedValues.filter((v) => v !== "all");
      }
      if (categoryValue === "all" && checked) {
        updatedValues = ["all"];
      }
      setSelectedItems(updatedValues);
      onCategoryChange(updatedValues);
    },
    [selectedItems, onCategoryChange]
  );
  return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-wrap items-center gap-2.5", children: categories.map((category) => {
    const isChecked = selectedItems.includes(category.value);
    return /* @__PURE__ */ jsxs(
      Label,
      {
        className: "flex cursor-pointer items-center gap-2.5 rounded-full bg-muted px-2.5 py-1.5",
        children: [
          /* @__PURE__ */ jsx("span", { children: category.label }),
          /* @__PURE__ */ jsx(
            Checkbox,
            {
              checked: isChecked,
              onCheckedChange: (checked) => handleCheckboxChange(!!checked, category.value)
            }
          )
        ]
      },
      category.value
    );
  }) });
};
var ResourcesResult = ({
  posts,
  categories,
  postsPerPage,
  loadMoreText,
  categoriesClassName,
  postsClassName,
  optixFlowConfig
}) => {
  const [visibleCount, setVisibleCount] = useState(postsPerPage);
  const [selectedCategories, setSelectedCategories] = useState([
    "all"
  ]);
  const handleCategoryChange = useCallback((selected) => {
    setSelectedCategories(selected);
    setVisibleCount(postsPerPage);
  }, [postsPerPage]);
  const handleLoadMore = useCallback(() => {
    setVisibleCount((prev) => prev + postsPerPage);
  }, [postsPerPage]);
  const filteredPosts = useMemo(() => {
    return posts.filter(
      (post) => selectedCategories.includes(post.category.toLowerCase()) || selectedCategories.includes("all")
    );
  }, [posts, selectedCategories]);
  const postsToDisplay = filteredPosts.length > 0 ? filteredPosts : posts;
  const hasMore = visibleCount < postsToDisplay.length;
  return /* @__PURE__ */ jsxs("div", { children: [
    /* @__PURE__ */ jsx("div", { className: categoriesClassName, children: /* @__PURE__ */ jsx(
      FilterForm,
      {
        categories,
        onCategoryChange: handleCategoryChange
      }
    ) }),
    /* @__PURE__ */ jsxs("div", { className: cn("flex w-full flex-col gap-4 py-8", postsClassName), children: [
      /* @__PURE__ */ jsx("div", { className: "grid gap-10 md:grid-cols-2 lg:grid-cols-3", children: postsToDisplay.slice(0, visibleCount).map((post, idx) => /* @__PURE__ */ jsx(ResourceCard, { ...post, optixFlowConfig }, idx)) }),
      hasMore && /* @__PURE__ */ jsx(
        Pressable,
        {
          className: "w-full",
          variant: "secondary",
          asButton: true,
          onClick: handleLoadMore,
          children: loadMoreText
        }
      )
    ] })
  ] });
};
var BreadcrumbBlog = ({ breadcrumb }) => {
  return /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, { children: breadcrumb.map((item, i) => {
    return /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsx(BreadcrumbLink, { href: item.link, children: item.label }) }),
      i < breadcrumb.length - 1 ? /* @__PURE__ */ jsx(BreadcrumbSeparator, { children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/slash", size: 16 }) }) : null
    ] }, `${item.label}`);
  }) }) });
};
var EmailForm = ({
  emailPlaceholder,
  buttonText,
  formConfig,
  onSubmit,
  onSuccess,
  onError
}) => {
  const form = useForm({
    initialValues: {
      email: ""
    },
    validationSchema: {
      email: (value) => {
        if (!value) return "Email is required";
        if (!isValidEmail(value)) return "Please enter a valid email address";
        return void 0;
      }
    },
    onSubmit: async (values, helpers) => {
      const shouldAutoSubmit = Boolean(formConfig?.endpoint);
      if (!shouldAutoSubmit && !onSubmit) {
        return;
      }
      try {
        let result;
        if (shouldAutoSubmit) {
          result = await submitPageSpeedForm(values, formConfig);
        }
        if (onSubmit) {
          await onSubmit(values.email);
        }
        if (shouldAutoSubmit || onSubmit) {
          if (formConfig?.resetOnSuccess !== false) {
            helpers.resetForm();
          }
          onSuccess?.(result);
        }
      } catch (error) {
        if (error instanceof PageSpeedFormSubmissionError && error.formErrors) {
          helpers.setErrors(error.formErrors);
        }
        onError?.(error);
        throw error;
      }
    }
  });
  const formMethod = formConfig?.method?.toLowerCase() === "get" ? "get" : "post";
  return /* @__PURE__ */ jsx(
    Form,
    {
      form,
      action: formConfig?.endpoint,
      method: formMethod,
      className: "w-full",
      children: /* @__PURE__ */ jsx(Field, { name: "email", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
        /* @__PURE__ */ jsxs("div", { className: "relative flex w-full flex-col gap-2 lg:block", children: [
          /* @__PURE__ */ jsx(
            TextInput,
            {
              ...field,
              type: "email",
              placeholder: emailPlaceholder,
              error: meta.touched && !!meta.error,
              className: "h-fit bg-background py-4 pr-5 pl-5 lg:pr-55",
              "aria-label": emailPlaceholder
            }
          ),
          /* @__PURE__ */ jsx("div", { className: "top-1/2 right-2.5 lg:absolute lg:-translate-y-1/2", children: /* @__PURE__ */ jsxs(
            Pressable,
            {
              componentType: "button",
              type: "submit",
              className: "w-full rounded-full lg:w-fit",
              variant: "default",
              asButton: true,
              disabled: form.isSubmitting,
              children: [
                buttonText,
                /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16, className: "ml-2" })
              ]
            }
          ) })
        ] }),
        meta.touched && meta.error && /* @__PURE__ */ jsx("p", { className: "py-1 text-sm text-destructive", children: meta.error })
      ] }) })
    }
  );
};
var ResourceCard = ({
  category,
  categoryLabel,
  title,
  thumbnail,
  summary,
  link,
  cta,
  className,
  optixFlowConfig
}) => {
  return /* @__PURE__ */ jsx(Pressable, { href: link, className: cn("block h-full w-full", className), children: /* @__PURE__ */ jsx(Card, { className: "size-full border py-0", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-0", children: [
    /* @__PURE__ */ jsx("div", { className: "border-b p-2.5 text-sm leading-[1.2] font-medium text-muted-foreground", children: categoryLabel ?? category }),
    /* @__PURE__ */ jsx(AspectRatio, { ratio: 1.520833333, className: "overflow-hidden", children: /* @__PURE__ */ jsx(
      Img,
      {
        src: thumbnail,
        alt: typeof title === "string" ? title : "Resource",
        className: "block size-full object-cover object-center",
        optixFlowConfig
      }
    ) }),
    /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-5 p-5", children: [
      typeof title === "string" ? /* @__PURE__ */ jsx("h2", { className: "text-lg leading-none font-bold md:text-2xl", children: title }) : /* @__PURE__ */ jsx("div", { className: "text-lg leading-none font-bold md:text-2xl", children: title }),
      /* @__PURE__ */ jsx("div", { className: "w-full max-w-[20rem]", children: typeof summary === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm leading-[1.4] font-medium text-foreground", children: summary }) : /* @__PURE__ */ jsx("div", { className: "text-sm leading-[1.4] font-medium text-foreground", children: summary }) }),
      /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Badge, { className: "rounded-full", children: [
        cta,
        /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 14, className: "ml-1" })
      ] }) })
    ] })
  ] }) }) });
};
function ResourceListHeroFilter({
  className,
  title,
  titleClassName,
  description,
  descriptionClassName,
  breadcrumb,
  breadcrumbSlot,
  breadcrumbClassName,
  primaryPost,
  primaryPostSlot,
  primaryPostClassName,
  posts,
  postsSlot,
  postsClassName,
  categories,
  categoriesClassName,
  allPostsTitle,
  allPostsTitleClassName,
  emailPlaceholder,
  buttonText,
  postsPerPage = 6,
  loadMoreText,
  heroClassName,
  contentClassName,
  heroPatternUrl,
  heroPatternSize = "3.125rem 3.125rem",
  formConfig,
  onSubmit,
  onSuccess,
  onError,
  optixFlowConfig
}) {
  const renderBreadcrumb = () => {
    if (breadcrumbSlot) return breadcrumbSlot;
    if (!breadcrumb || breadcrumb.length === 0) return null;
    return /* @__PURE__ */ jsx("div", { className: breadcrumbClassName, children: /* @__PURE__ */ jsx(BreadcrumbBlog, { breadcrumb }) });
  };
  const renderPrimaryPost = () => {
    if (primaryPostSlot) return primaryPostSlot;
    if (!primaryPost) return null;
    return /* @__PURE__ */ jsx("div", { className: cn("w-full max-w-110", primaryPostClassName), children: /* @__PURE__ */ jsx(ResourceCard, { ...primaryPost, optixFlowConfig }) });
  };
  const renderPosts = () => {
    if (postsSlot) return postsSlot;
    if (!posts || posts.length === 0) return null;
    return /* @__PURE__ */ jsx(
      ResourcesResult,
      {
        posts,
        categories: categories ?? [],
        postsPerPage,
        loadMoreText,
        categoriesClassName,
        postsClassName,
        optixFlowConfig
      }
    );
  };
  return /* @__PURE__ */ jsxs("section", { className: cn("pb-32", className), children: [
    /* @__PURE__ */ jsx(
      "div",
      {
        className: cn("bg-muted bg-repeat", heroClassName),
        style: {
          backgroundImage: `url('${heroPatternUrl ?? patternSvgs.dotPattern2}')`,
          backgroundSize: heroPatternSize
        },
        children: /* @__PURE__ */ jsxs("div", { className: "container flex flex-col items-start justify-start gap-16 py-20 lg:flex-row lg:items-center lg:justify-between", children: [
          /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col justify-between gap-12", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-xl flex-col gap-8", children: [
            renderBreadcrumb(),
            /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-5", children: [
              title && (typeof title === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("text-[2.5rem] leading-[1.2] font-semibold md:text-5xl lg:text-6xl", titleClassName), children: title }) : /* @__PURE__ */ jsx("div", { className: titleClassName, children: title })),
              description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-xl leading-[1.4] font-semibold text-foreground", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
            ] }),
            /* @__PURE__ */ jsx("div", { className: "max-w-120", children: /* @__PURE__ */ jsx(
              EmailForm,
              {
                emailPlaceholder,
                buttonText,
                formConfig,
                onSubmit,
                onSuccess,
                onError
              }
            ) })
          ] }) }),
          renderPrimaryPost()
        ] })
      }
    ),
    /* @__PURE__ */ jsx("div", { className: cn("py-20", contentClassName), children: /* @__PURE__ */ jsxs("div", { className: "container flex flex-col gap-8", children: [
      allPostsTitle && (typeof allPostsTitle === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-[1.75rem] leading-none font-medium md:text-[2.25rem] lg:text-[2rem]", allPostsTitleClassName), children: allPostsTitle }) : /* @__PURE__ */ jsx("div", { className: allPostsTitleClassName, children: allPostsTitle })),
      /* @__PURE__ */ jsx("div", { children: renderPosts() })
    ] }) })
  ] });
}

export { ResourceListHeroFilter };
