/* ============================================================
   GooeyInput — a click-to-expand search control with an SVG
   "gooey" filter. Ported from Aceternity UI's <GooeyInput/> to
   this no-build React + Babel site: framer-motion's shared-layout
   animation is replaced with plain CSS transitions, and the
   "use client" / module imports are dropped (these babel scripts
   share one global lexical scope — see companies.jsx).

   The collapsed pill (icon + label) expands into a text field
   while a detached bubble blobs out on the left; the
   feGaussianBlur + feColorMatrix goo filter merges the two shapes
   like liquid metal, then feComposite re-paints the crisp label /
   input on top so text stays sharp.

   Controlled usage (what every Kestrel search bar uses):
     <GooeyInput value={q} onValueChange={setQ}
                 placeholder="Search…" expandedWidth={300} />

   Props: placeholder, collapsedLabel, collapsedWidth, expandedWidth,
   expandedOffset, gooeyBlur, value, defaultValue, onValueChange,
   onOpenChange, align ('start'|'center'), surface (CSS color),
   className, style. Styles live in gooey.css. Registers window.GooeyInput.
   ============================================================ */

const GooeySearchGlyph = ({ size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
    strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} className="gooey-glyph" aria-hidden>
    <circle cx="11" cy="11" r="8" />
    <path d="m21 21-4.3-4.3" />
  </svg>
);

/* The metaball filter. SourceGraphic is blurred, the alpha is then
   pushed to a hard edge (×20 −10) to fuse nearby shapes, and the
   original graphic is composited back on top ("atop") so the label
   and input text remain crisp over the gooey blobs. */
const GooeyFilter = ({ filterId, blur }) => (
  <svg className="gooey-svg" width="0" height="0" aria-hidden focusable="false">
    <defs>
      <filter id={filterId} x="-50%" y="-50%" width="200%" height="200%" colorInterpolationFilters="sRGB">
        <feGaussianBlur in="SourceGraphic" stdDeviation={blur} result="blur" />
        <feColorMatrix in="blur" type="matrix"
          values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 20 -10" result="goo" />
        <feComposite in="SourceGraphic" in2="goo" operator="atop" />
      </filter>
    </defs>
  </svg>
);

const GooeyInput = ({
  placeholder = 'Search…',
  collapsedLabel = 'Search',
  collapsedWidth = 128,
  expandedWidth = 240,
  expandedOffset = 50,
  gooeyBlur = 5,
  value,
  defaultValue = '',
  onValueChange,
  onOpenChange,
  align = 'start',
  surface,
  className,
  style,
}) => {
  const rawId = React.useId();
  const filterId = 'gooey' + String(rawId).replace(/:/g, '');

  const inputRef = React.useRef(null);
  const prevExpanded = React.useRef(false);
  const [isExpanded, setIsExpanded] = React.useState(false);
  const [uncontrolled, setUncontrolled] = React.useState(defaultValue);

  const isControlled = value !== undefined;
  const text = isControlled ? value : uncontrolled;

  const setText = (next) => {
    if (!isControlled) setUncontrolled(next);
    if (onValueChange) onValueChange(next);
  };
  const setExpanded = (next) => {
    setIsExpanded(next);
    if (onOpenChange) onOpenChange(next);
  };

  // Focus on expand; clear the query when it collapses (mirrors the
  // Aceternity behaviour + restores the "no query" view, e.g. the
  // companies marquee).
  React.useEffect(() => {
    if (isExpanded) {
      if (inputRef.current) inputRef.current.focus();
    } else if (prevExpanded.current && text) {
      setText('');
    }
    prevExpanded.current = isExpanded;
  }, [isExpanded]);

  const focusOrExpand = () => {
    if (isExpanded) { if (inputRef.current) inputRef.current.focus(); }
    else setExpanded(true);
  };
  const onPillKey = (e) => {
    if (!isExpanded && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); setExpanded(true); }
  };
  const onFieldKey = (e) => {
    if (e.key === 'Escape') { setText(''); setExpanded(false); }
  };
  const handleBlur = () => { if (!text) setExpanded(false); };

  const rootStyle = surface ? { ['--gooey-surface']: surface, ...(style || {}) } : style;
  const rootClass = 'gooey-root'
    + (align === 'center' ? ' gooey-center' : '')
    + (className ? ' ' + className : '');

  return (
    <div className={rootClass} data-expanded={isExpanded ? '1' : '0'} style={rootStyle}>
      <GooeyFilter filterId={filterId} blur={gooeyBlur} />
      <div className="gooey-stage" style={{ filter: `url(#${filterId})` }}>
        <div className="gooey-row" style={{ width: isExpanded ? expandedWidth : collapsedWidth, marginLeft: isExpanded ? expandedOffset : 0 }}>
          <div className="gooey-pill" role="button" tabIndex={isExpanded ? -1 : 0}
            aria-label={collapsedLabel} aria-expanded={isExpanded}
            onClick={focusOrExpand} onKeyDown={onPillKey}>
            {!isExpanded && <GooeySearchGlyph />}
            {!isExpanded && <span className="gooey-label">{collapsedLabel}</span>}
            {isExpanded && (
              <input ref={inputRef} type="search" enterKeyHint="search" autoComplete="off" spellCheck={false}
                className="gooey-field" value={text} placeholder={placeholder} aria-label={placeholder}
                onChange={(e) => setText(e.target.value)} onBlur={handleBlur} onKeyDown={onFieldKey} />
            )}
          </div>
        </div>
        <div className="gooey-bubble" aria-hidden>
          <span className="gooey-bubble-surface"><GooeySearchGlyph /></span>
        </div>
      </div>
    </div>
  );
};

window.GooeyInput = GooeyInput;
