<script lang="ts">
  export let content: string;
  export let searchQuery: string;

  interface TextPart {
    text: string;
    isMatch: boolean;
  }

  function getHighlightedParts(text: string, query: string): TextPart[] {
    if (!query) {
      return [{ text, isMatch: false }];
    }

    const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    const regex = new RegExp(`(${escapedQuery})`, "gi");
    const parts: TextPart[] = [];
    let lastIndex = 0;
    let match: RegExpExecArray | null;

    while ((match = regex.exec(text)) !== null) {
      // Add non-matching text before the match
      if (match.index > lastIndex) {
        parts.push({
          text: text.slice(lastIndex, match.index),
          isMatch: false,
        });
      }

      // Add the matching text
      parts.push({
        text: match[1],
        isMatch: true,
      });

      lastIndex = regex.lastIndex;
    }

    // Add any remaining text after the last match
    if (lastIndex < text.length) {
      parts.push({
        text: text.slice(lastIndex),
        isMatch: false,
      });
    }

    return parts;
  }

  $: parts = getHighlightedParts(content, searchQuery);
</script>

<span class="whitespace-pre-wrap">
  {#each parts as part, index (index)}
    {#if part.isMatch}
      <mark class="search-highlight">{part.text}</mark>
    {:else}
      {part.text}
    {/if}
  {/each}
</span>
