import { useState, useMemo, useCallback } from 'react';
import type { Message } from './use-socket.js';

export interface SearchMatch {
  messageIndex: number;
  charOffset: number;
}

export interface UseSearchReturn {
  query: string;
  setQuery: (q: string) => void;
  matches: SearchMatch[];
  currentMatchIndex: number;
  nextMatch: () => void;
  prevMatch: () => void;
  clear: () => void;
  totalMatches: number;
}

export function useSearch(messages: Message[]): UseSearchReturn {
  const [query, setQuery] = useState('');
  const [currentMatchIndex, setCurrentMatchIndex] = useState(0);

  const matches = useMemo<SearchMatch[]>(() => {
    if (query.length < 2) return [];

    const lowerQuery = query.toLowerCase();
    const result: SearchMatch[] = [];

    for (let i = 0; i < messages.length; i++) {
      const msg = messages[i];
      if (!msg) continue;
      const content = msg.content.toLowerCase();
      let offset = 0;
      while (true) {
        const idx = content.indexOf(lowerQuery, offset);
        if (idx === -1) break;
        result.push({ messageIndex: i, charOffset: idx });
        offset = idx + 1;
      }
    }

    return result;
  }, [query, messages]);

  // Reset match index when matches change
  useMemo(() => {
    setCurrentMatchIndex(0);
  }, [matches]);

  const nextMatch = useCallback(() => {
    if (matches.length === 0) return;
    setCurrentMatchIndex((prev) => (prev + 1) % matches.length);
  }, [matches.length]);

  const prevMatch = useCallback(() => {
    if (matches.length === 0) return;
    setCurrentMatchIndex((prev) => (prev - 1 + matches.length) % matches.length);
  }, [matches.length]);

  const clear = useCallback(() => {
    setQuery('');
    setCurrentMatchIndex(0);
  }, []);

  return {
    query,
    setQuery,
    matches,
    currentMatchIndex,
    nextMatch,
    prevMatch,
    clear,
    totalMatches: matches.length,
  };
}
