"use client";
import * as React4 from 'react';
import { MapLibre } from '@page-speed/maps';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { cva } from 'class-variance-authority';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { Icon } from '@page-speed/icon';
import { Img } from '@page-speed/img';

// components/ui/geo-map.tsx
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 = React4.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 = React4.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 = React4.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 = React4.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 = React4.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 = React4.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 DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
var DynamicIcon = React4.memo(function DynamicIcon2({
  apiKey,
  ...props
}) {
  return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
});
DynamicIcon.displayName = "DynamicIcon";
var PANEL_POSITION_CLASS = {
  "top-left": "left-4 top-4",
  "top-right": "right-4 top-4",
  "bottom-left": "bottom-4 left-4",
  "bottom-right": "bottom-4 right-4"
};
var DEFAULT_VIEW_STATE = {
  latitude: 39.5,
  longitude: -98.35,
  zoom: 3
};
var VIDEO_FILE_EXTENSION_REGEX = /\.(mp4|webm|ogg|mov|m4v|m3u8)(\?.*)?$/i;
function resolveMediaType(item) {
  if (item.type) {
    return item.type;
  }
  return VIDEO_FILE_EXTENSION_REGEX.test(item.src) ? "video" : "image";
}
function normalizeId(value, fallback) {
  if (value === null || value === void 0 || value === "") {
    return fallback;
  }
  return String(value);
}
function buildClusterCenter(markers) {
  if (!markers.length) {
    return null;
  }
  const total = markers.reduce(
    (accumulator, marker) => ({
      latitude: accumulator.latitude + marker.latitude,
      longitude: accumulator.longitude + marker.longitude
    }),
    { latitude: 0, longitude: 0 }
  );
  return {
    latitude: total.latitude / markers.length,
    longitude: total.longitude / markers.length
  };
}
function resolveActionKey(action, index) {
  if (typeof action.label === "string" && action.label.trim().length > 0) {
    return `label:${action.label}:${index}`;
  }
  if (action.href) {
    return `href:${action.href}:${index}`;
  }
  return `action:${index}`;
}
function MarkerActions({ actions }) {
  if (!actions || actions.length === 0) {
    return null;
  }
  return /* @__PURE__ */ jsx("div", { className: "mt-4 flex flex-wrap gap-2", children: actions.map((action, index) => {
    const {
      label,
      icon,
      iconAfter,
      children,
      href,
      onClick,
      className: actionClassName,
      variant,
      size,
      asButton,
      ...rest
    } = action;
    return /* @__PURE__ */ jsx(
      Pressable,
      {
        href,
        onClick,
        variant: variant ?? (index === 0 ? "default" : "outline"),
        size: size ?? "sm",
        asButton: asButton ?? true,
        className: cn("inline-flex items-center gap-2", actionClassName),
        ...rest,
        children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
          icon,
          label,
          iconAfter
        ] })
      },
      resolveActionKey(action, index)
    );
  }) });
}
function MarkerMediaCarousel({
  mediaItems,
  optixFlowConfig
}) {
  const [activeIndex, setActiveIndex] = React4.useState(0);
  const totalItems = mediaItems.length;
  const mediaResetKey = React4.useMemo(
    () => mediaItems.map((item, index) => {
      const itemId = normalizeId(item.id, `media-${index}`);
      return `${itemId}:${item.src}:${item.type ?? ""}:${item.poster ?? ""}`;
    }).join("|"),
    [mediaItems]
  );
  const activeItemIndex = Math.min(activeIndex, Math.max(0, totalItems - 1));
  React4.useEffect(() => {
    setActiveIndex(0);
  }, [mediaResetKey]);
  return /* @__PURE__ */ jsxs("div", { className: "relative border-b border-border/60 bg-muted/40", children: [
    /* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden", children: mediaItems.map((item, index) => {
      const isActive = index === activeItemIndex;
      const mediaType = resolveMediaType(item);
      return /* @__PURE__ */ jsx(
        "div",
        {
          "aria-hidden": !isActive,
          className: cn(
            "absolute inset-0 transition-opacity duration-500 ease-in-out",
            isActive ? "opacity-100 z-[1]" : "opacity-0 z-0 pointer-events-none"
          ),
          children: mediaType === "video" ? /* @__PURE__ */ jsx(
            "video",
            {
              className: "h-full w-full object-cover",
              controls: isActive,
              preload: "metadata",
              poster: item.poster,
              tabIndex: isActive ? 0 : -1,
              children: /* @__PURE__ */ jsx("source", { src: item.src })
            }
          ) : /* @__PURE__ */ jsx(
            Img,
            {
              src: item.src,
              alt: item.alt ?? "Map marker media",
              className: "h-full w-full object-cover",
              loading: "eager",
              optixFlowConfig
            }
          )
        },
        normalizeId(item.id, `media-slide-${index}`)
      );
    }) }),
    totalItems > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx(
        "button",
        {
          type: "button",
          "aria-label": "Show previous media",
          className: "absolute left-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
          onClick: () => {
            setActiveIndex(
              (current) => (current - 1 + totalItems) % totalItems
            );
          },
          children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-left", size: 18 })
        }
      ),
      /* @__PURE__ */ jsx(
        "button",
        {
          type: "button",
          "aria-label": "Show next media",
          className: "absolute right-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
          onClick: () => {
            setActiveIndex((current) => (current + 1) % totalItems);
          },
          children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 18 })
        }
      ),
      /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center gap-1.5 z-[2]", children: mediaItems.map((item, index) => /* @__PURE__ */ jsx(
        "button",
        {
          type: "button",
          "aria-label": `Show media item ${index + 1}`,
          className: cn(
            "h-2 rounded-full transition-all duration-300",
            index === activeItemIndex ? "w-6 bg-card" : "w-2 bg-card opacity-50 hover:opacity-100"
          ),
          onClick: () => setActiveIndex(index)
        },
        normalizeId(item.id, `media-dot-${index}`)
      )) })
    ] }) : null
  ] });
}
function getMarkerTitle(marker, markerIndex) {
  if (marker.title !== void 0 && marker.title !== null) {
    return marker.title;
  }
  if (marker.label !== void 0 && marker.label !== null) {
    return marker.label;
  }
  return `Location ${markerIndex + 1}`;
}
function GeoMap({
  className,
  mapWrapperClassName,
  mapClassName,
  panelClassName,
  panelPosition = "top-left",
  stadiaApiKey = "",
  mapStyle = "osm-bright",
  styleUrl,
  mapLibreCssHref,
  markers = [],
  clusters = [],
  viewState,
  defaultViewState,
  onViewStateChange,
  onMapClick,
  onMarkerDrag,
  showNavigationControl = true,
  showGeolocateControl = false,
  navigationControlPosition = "top-right",
  geolocateControlPosition = "top-left",
  flyToOptions,
  markerFocusZoom = 14,
  clusterFocusZoom = 5,
  selectedMarkerId,
  initialSelectedMarkerId,
  onSelectionChange,
  clearSelectionOnMapClick = true,
  mapChildren,
  optixFlowConfig
}) {
  const normalizedStandaloneMarkers = React4.useMemo(
    () => markers.map((marker, index) => ({
      ...marker,
      id: normalizeId(marker.id, `marker-${index}`)
    })),
    [markers]
  );
  const normalizedClusters = React4.useMemo(() => {
    const results = [];
    clusters.forEach((cluster, clusterIndex) => {
      const clusterId = normalizeId(cluster.id, `cluster-${clusterIndex}`);
      const normalizedClusterMarkers = cluster.markers.map(
        (marker, markerIndex) => ({
          ...marker,
          id: normalizeId(marker.id, `${clusterId}-marker-${markerIndex}`),
          clusterId
        })
      );
      const clusterCenter = cluster.latitude !== void 0 && cluster.longitude !== void 0 ? { latitude: cluster.latitude, longitude: cluster.longitude } : buildClusterCenter(normalizedClusterMarkers);
      if (!clusterCenter) {
        return;
      }
      results.push({
        ...cluster,
        id: clusterId,
        latitude: clusterCenter.latitude,
        longitude: clusterCenter.longitude,
        markers: normalizedClusterMarkers
      });
    });
    return results;
  }, [clusters]);
  const markerLookup = React4.useMemo(() => {
    const lookup = /* @__PURE__ */ new Map();
    normalizedStandaloneMarkers.forEach((marker) => {
      lookup.set(marker.id, marker);
    });
    normalizedClusters.forEach((cluster) => {
      cluster.markers.forEach((marker) => {
        lookup.set(marker.id, marker);
      });
    });
    return lookup;
  }, [normalizedClusters, normalizedStandaloneMarkers]);
  const clusterLookup = React4.useMemo(() => {
    const lookup = /* @__PURE__ */ new Map();
    normalizedClusters.forEach((cluster) => {
      lookup.set(cluster.id, cluster);
    });
    return lookup;
  }, [normalizedClusters]);
  const firstCoordinate = React4.useMemo(() => {
    if (normalizedStandaloneMarkers.length > 0) {
      const firstStandaloneMarker = normalizedStandaloneMarkers[0];
      return {
        latitude: firstStandaloneMarker.latitude,
        longitude: firstStandaloneMarker.longitude
      };
    }
    if (normalizedClusters.length > 0) {
      const firstCluster = normalizedClusters[0];
      return {
        latitude: firstCluster.latitude,
        longitude: firstCluster.longitude
      };
    }
    return {
      latitude: DEFAULT_VIEW_STATE.latitude,
      longitude: DEFAULT_VIEW_STATE.longitude
    };
  }, [normalizedClusters, normalizedStandaloneMarkers]);
  const [uncontrolledViewState, setUncontrolledViewState] = React4.useState({
    latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
    longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
    zoom: defaultViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom
  });
  const isControlledViewState = viewState !== void 0;
  const resolvedViewState = isControlledViewState ? viewState : uncontrolledViewState;
  const applyViewState = React4.useCallback(
    (nextState) => {
      if (!isControlledViewState) {
        setUncontrolledViewState((current) => {
          const next = { ...current, ...nextState };
          const hasChanged = current.latitude !== next.latitude || current.longitude !== next.longitude || current.zoom !== next.zoom;
          return hasChanged ? next : current;
        });
      }
      onViewStateChange?.(nextState);
    },
    [isControlledViewState, onViewStateChange]
  );
  const [selection, setSelection] = React4.useState(() => {
    if (initialSelectedMarkerId !== void 0 && initialSelectedMarkerId !== null) {
      return {
        type: "marker",
        markerId: String(initialSelectedMarkerId)
      };
    }
    return { type: "none" };
  });
  React4.useEffect(() => {
    if (selectedMarkerId === void 0 || selectedMarkerId === null) {
      return;
    }
    setSelection({
      type: "marker",
      markerId: String(selectedMarkerId)
    });
  }, [selectedMarkerId]);
  const selectedMarker = selection.markerId ? markerLookup.get(selection.markerId) : void 0;
  const selectedCluster = selection.clusterId ? clusterLookup.get(selection.clusterId) : void 0;
  React4.useEffect(() => {
    if (selection.type === "marker" && selection.markerId && !selectedMarker) {
      setSelection({ type: "none" });
      onSelectionChange?.({ type: "none" });
    }
  }, [onSelectionChange, selectedMarker, selection]);
  const emitSelectionChange = React4.useCallback(
    (nextSelection) => {
      if (nextSelection.type === "none") {
        onSelectionChange?.({ type: "none" });
        return;
      }
      if (nextSelection.type === "marker") {
        const parentCluster = nextSelection.marker.clusterId ? clusterLookup.get(nextSelection.marker.clusterId) : void 0;
        onSelectionChange?.({
          type: "marker",
          marker: nextSelection.marker,
          cluster: parentCluster
        });
        return;
      }
      onSelectionChange?.({
        type: "cluster",
        cluster: nextSelection.cluster
      });
    },
    [clusterLookup, onSelectionChange]
  );
  const selectMarker = React4.useCallback(
    (marker) => {
      setSelection({
        type: "marker",
        markerId: marker.id,
        clusterId: marker.clusterId
      });
      applyViewState({
        latitude: marker.latitude,
        longitude: marker.longitude,
        zoom: markerFocusZoom
      });
      emitSelectionChange({ type: "marker", marker });
    },
    [applyViewState, emitSelectionChange, markerFocusZoom]
  );
  const selectCluster = React4.useCallback(
    (cluster) => {
      setSelection({
        type: "cluster",
        clusterId: cluster.id
      });
      applyViewState({
        latitude: cluster.latitude,
        longitude: cluster.longitude,
        zoom: clusterFocusZoom
      });
      emitSelectionChange({ type: "cluster", cluster });
    },
    [applyViewState, clusterFocusZoom, emitSelectionChange]
  );
  const clearSelection = React4.useCallback(() => {
    setSelection({ type: "none" });
    emitSelectionChange({ type: "none" });
  }, [emitSelectionChange]);
  const mapMarkers = React4.useMemo(() => {
    const resolvedMarkers = [];
    normalizedClusters.forEach((cluster) => {
      const isSelected = selection.type === "cluster" && selection.clusterId === cluster.id;
      resolvedMarkers.push({
        id: `cluster-pin:${cluster.id}`,
        latitude: cluster.latitude,
        longitude: cluster.longitude,
        element: () => {
          const customMarkerElement = cluster.markerElement;
          const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({
            isSelected,
            count: cluster.markers.length
          }) : customMarkerElement;
          return /* @__PURE__ */ jsx(
            "button",
            {
              type: "button",
              className: "group cursor-pointer",
              onClick: (event) => {
                event.preventDefault();
                event.stopPropagation();
                selectCluster(cluster);
              },
              "aria-label": `View ${cluster.markers.length} clustered locations`,
              children: markerBody ?? /* @__PURE__ */ jsx(
                "span",
                {
                  className: cn(
                    "inline-flex min-h-10 min-w-10 items-center justify-center rounded-full border-2 border-white px-2 text-xs font-semibold text-white shadow-lg transition-transform duration-200 group-hover:scale-105",
                    isSelected && "ring-4 ring-primary/30",
                    cluster.pinClassName
                  ),
                  style: {
                    backgroundColor: cluster.pinColor ?? "var(--foreground)"
                  },
                  children: cluster.markers.length
                }
              )
            }
          );
        }
      });
    });
    normalizedStandaloneMarkers.forEach((marker) => {
      const isSelected = selection.type === "marker" && selection.markerId === marker.id;
      const customMarkerElement = marker.markerElement;
      resolvedMarkers.push({
        id: marker.id,
        latitude: marker.latitude,
        longitude: marker.longitude,
        draggable: marker.draggable,
        element: () => {
          const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({ isSelected }) : customMarkerElement;
          return /* @__PURE__ */ jsx(
            "button",
            {
              type: "button",
              className: "group cursor-pointer",
              onClick: (event) => {
                event.preventDefault();
                event.stopPropagation();
                selectMarker(marker);
              },
              "aria-label": typeof marker.title === "string" ? `View ${marker.title}` : "View location details",
              children: markerBody ?? /* @__PURE__ */ jsx(
                "span",
                {
                  className: cn(
                    "inline-flex h-4 w-4 rounded-full border-2 border-white shadow-md transition-transform duration-200 group-hover:scale-110",
                    isSelected && "h-5 w-5 ring-4 ring-primary/30",
                    marker.pinClassName
                  ),
                  style: {
                    backgroundColor: marker.pinColor ?? "#f43f5e"
                  }
                }
              )
            }
          );
        }
      });
    });
    return resolvedMarkers;
  }, [
    normalizedClusters,
    normalizedStandaloneMarkers,
    selectCluster,
    selectMarker,
    selection
  ]);
  const renderMarkerPanel = () => {
    if (selectedMarker) {
      const markerMediaItems = selectedMarker.mediaItems ?? [];
      return /* @__PURE__ */ jsxs(
        "div",
        {
          className: cn(
            "relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
            panelClassName
          ),
          children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                "aria-label": "Close marker details",
                className: "\n            flex size-12 items-center justify-center rounded-bl-lg rounded-br-0 rounded-t-0 bg-black text-white transition-all duration-500 absolute top-0 right-0 z-10 cursor-pointer ring-4 ring-white\n",
                onClick: clearSelection,
                children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
              }
            ),
            markerMediaItems.length > 0 ? /* @__PURE__ */ jsx(
              MarkerMediaCarousel,
              {
                mediaItems: markerMediaItems,
                optixFlowConfig
              }
            ) : null,
            /* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
              /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
                selectedMarker.eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide", children: selectedMarker.eyebrow }) : null,
                /* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight", children: selectedMarker.title ?? selectedMarker.label ?? "Location" })
              ] }) }),
              selectedMarker.summary ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed", children: selectedMarker.summary }) : null,
              selectedMarker.locationLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
                /* @__PURE__ */ jsx(
                  DynamicIcon,
                  {
                    name: "lucide:map-pin",
                    className: "opacity-50",
                    size: 18
                  }
                ),
                typeof selectedMarker.locationLine === "string" ? /* @__PURE__ */ jsx(
                  Pressable,
                  {
                    href: selectedMarker.locationUrl,
                    className: cn(
                      "transition-all duration-500",
                      "font-medium opacity-75 hover:opacity-100",
                      selectedMarker.locationUrl ? "underline underline-offset-4" : ""
                    ),
                    children: selectedMarker.locationLine
                  }
                ) : selectedMarker.locationLine
              ] }) : null,
              selectedMarker.hoursLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
                /* @__PURE__ */ jsx(
                  DynamicIcon,
                  {
                    name: "lucide:clock",
                    className: "opacity-50",
                    size: 18
                  }
                ),
                typeof selectedMarker.hoursLine === "string" ? /* @__PURE__ */ jsx("div", { className: "font-medium", children: selectedMarker.hoursLine }) : selectedMarker.hoursLine
              ] }) : null,
              selectedMarker.markerContentComponent ? /* @__PURE__ */ jsx("div", { className: "relative", children: selectedMarker.markerContentComponent }) : null,
              /* @__PURE__ */ jsx(MarkerActions, { actions: selectedMarker.actions })
            ] })
          ]
        }
      );
    }
    if (selectedCluster) {
      return /* @__PURE__ */ jsxs(
        "div",
        {
          className: cn(
            "relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
            panelClassName
          ),
          children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                "aria-label": "Close cluster details",
                className: "flex size-8 items-center justify-center rounded-full border border-border bg-card text-card-foreground transition hover:bg-muted hover:text-foreground absolute top-2 right-2 z-10",
                onClick: clearSelection,
                children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
              }
            ),
            /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
              selectedCluster.label ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: selectedCluster.label }) : null,
              /* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight text-foreground", children: selectedCluster.title ?? "Clustered Locations" }),
              /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: selectedCluster.summary ?? `${selectedCluster.markers.length} location${selectedCluster.markers.length === 1 ? "" : "s"} in this cluster.` })
            ] }) }),
            /* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-2 overflow-y-auto pr-1", children: selectedCluster.markers.map((marker, markerIndex) => /* @__PURE__ */ jsxs(
              "button",
              {
                type: "button",
                className: "w-full rounded-lg border border-border/60 p-3 text-left transition hover:border-border hover:bg-muted/50",
                onClick: () => selectMarker(marker),
                children: [
                  /* @__PURE__ */ jsx("div", { className: "line-clamp-1 text-sm font-semibold text-foreground", children: getMarkerTitle(marker, markerIndex) }),
                  marker.summary ? /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: marker.summary }) : null
                ]
              },
              marker.id
            )) })
          ]
        }
      );
    }
    return null;
  };
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: cn(
        "relative overflow-hidden rounded-2xl border border-border bg-background",
        className
      ),
      children: [
        /* @__PURE__ */ jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsx(
          MapLibre,
          {
            stadiaApiKey,
            mapStyle,
            styleUrl,
            mapLibreCssHref,
            viewState: resolvedViewState,
            onViewStateChange: applyViewState,
            markers: mapMarkers,
            onClick: (coord) => {
              onMapClick?.(coord);
              if (clearSelectionOnMapClick) {
                clearSelection();
              }
            },
            onMarkerDrag,
            showNavigationControl,
            showGeolocateControl,
            navigationControlPosition,
            geolocateControlPosition,
            flyToOptions,
            className: cn("h-full w-full", mapClassName),
            children: mapChildren
          }
        ) }),
        selection.type !== "none" ? /* @__PURE__ */ jsx(
          "div",
          {
            className: cn(
              "pointer-events-none absolute z-20",
              PANEL_POSITION_CLASS[panelPosition]
            ),
            children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
          }
        ) : null
      ]
    }
  );
}

export { GeoMap };
