import { Fragment, type ReactNode } from 'react';

/**
 * Wrap occurrences of `query` inside `text` with `<mark>` so the user
 * can see why a result matched. Case-insensitive, escapes regex meta-
 * chars in the query so a paste of "INV-2025" doesn't blow up.
 *
 * Tokenized matching - splits the query on whitespace and highlights
 * each token independently, so "joh smi" highlights both "Joh" and
 * "Smi" in "John Smith". Mirrors the prefix-tsquery the server uses.
 */
export function HighlightMatch({
  text,
  query,
  className,
}: {
  text: string | null | undefined;
  query: string;
  className?: string;
}): ReactNode {
  if (!text) return null;
  const tokens = query
    .trim()
    .split(/\s+/)
    .filter((t) => t.length > 0)
    .map(escapeRegex);
  if (tokens.length === 0) return text;

  const re = new RegExp(`(${tokens.join('|')})`, 'gi');
  const parts = text.split(re);

  return (
    <span className={className}>
      {parts.map((part, i) => {
        if (i % 2 === 1) {
          // The capture group lands on odd indices.
          return (
            <mark key={i} className="bg-brand/15 text-foreground rounded-[2px] px-px font-medium">
              {part}
            </mark>
          );
        }
        return <Fragment key={i}>{part}</Fragment>;
      })}
    </span>
  );
}

function escapeRegex(input: string): string {
  return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
