import * as React from "react";
import { cn } from "@/lib/utils";

export type SearchTextSegment = {
  text: string;
  matched: boolean;
};

/** Split display text into matched / unmatched segments (case-insensitive). */
export function splitTextBySearchQuery(
  text: string,
  query: string,
): SearchTextSegment[] {
  const q = query.trim();
  if (!text || !q) return [{ text, matched: false }];

  const lowerText = text.toLowerCase();
  const lowerQuery = q.toLowerCase();
  const segments: SearchTextSegment[] = [];
  let cursor = 0;

  while (cursor < text.length) {
    const matchIndex = lowerText.indexOf(lowerQuery, cursor);
    if (matchIndex === -1) {
      segments.push({ text: text.slice(cursor), matched: false });
      break;
    }

    if (matchIndex > cursor) {
      segments.push({ text: text.slice(cursor, matchIndex), matched: false });
    }

    segments.push({
      text: text.slice(matchIndex, matchIndex + q.length),
      matched: true,
    });
    cursor = matchIndex + q.length;
  }

  return segments.length > 0 ? segments : [{ text, matched: false }];
}

type HighlightSearchTextProps = {
  text: string;
  query: string;
  className?: string;
  highlightClassName?: string;
};

export function HighlightSearchText({
  text,
  query,
  className,
  highlightClassName,
}: HighlightSearchTextProps) {
  const segments = React.useMemo(
    () => splitTextBySearchQuery(text, query),
    [text, query],
  );

  return (
    <span className={className}>
      {segments.map((segment, index) =>
        segment.matched ? (
          <span
            key={`${index}-${segment.text}`}
            className={cn(
              "rounded-sm bg-yellow/25 font-semibold text-foreground",
              "group-data-[selected=true]/search-item:bg-white/35 group-data-[selected=true]/search-item:text-accent-foreground",
              highlightClassName,
            )}
          >
            {segment.text}
          </span>
        ) : (
          <React.Fragment key={`${index}-${segment.text}`}>
            {segment.text}
          </React.Fragment>
        ),
      )}
    </span>
  );
}
