/**
 * Autocomplete suggestion popup component for formula editor.
 * Displays suggestions for XBRL concepts and field references with keyboard navigation.
 */

import React, { useEffect, useRef, useMemo, useCallback } from 'react';
import type { SuggestionItem } from '../../lib/formulaAutocompleteUtils';

interface FormulaAutocompleteProps {
  /** Array of suggestions to display */
  suggestions: SuggestionItem[];
  /** Index of the currently selected suggestion */
  selectedIndex: number;
  /** Callback when a suggestion is selected */
  onSelect: (index: number) => void;
  /** Callback when hovering over a suggestion */
  onHover: (index: number) => void;
  /** Position for the popup */
  position: { top: number; left: number; width?: number };
  /** Optional maximum height for the suggestion list */
  maxHeight?: number;
  /** The current query string for highlighting matches */
  query: string;
  /** Optional custom class name for the container */
  className?: string;
}

/**
 * Highlights the matching part of the suggestion text.
 * @param text - The full suggestion text
 * @param query - The query string to highlight
 * @returns React node with highlighted match
 */
function highlightMatch(text: string, query: string): React.ReactNode {
  if (!query) {
    return text;
  }

  const lowerText = text.toLowerCase();
  const lowerQuery = query.toLowerCase();
  const matchIndex = lowerText.indexOf(lowerQuery);

  if (matchIndex === -1) {
    return text;
  }

  const before = text.substring(0, matchIndex);
  const match = text.substring(matchIndex, matchIndex + query.length);
  const after = text.substring(matchIndex + query.length);

  return (
    <>
      {before}
      <span className="bg-info/20 text-info font-semibold">{match}</span>
      {after}
    </>
  );
}

export const FormulaAutocomplete: React.FC<FormulaAutocompleteProps> = ({
  suggestions,
  selectedIndex,
  onSelect,
  onHover,
  position,
  maxHeight = 280,
  query,
  className = '',
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const scrollContainerRef = useRef<HTMLDivElement>(null);

  // Scroll selected item into view when selection changes
  useEffect(() => {
    if (scrollContainerRef.current && suggestions.length > 0) {
      const selectedElement = scrollContainerRef.current.querySelector(
        `[data-index="${selectedIndex}"]`
      ) as HTMLElement;
      if (selectedElement) {
        selectedElement.scrollIntoView({
          block: 'nearest',
          behavior: 'smooth',
        });
      }
    }
  }, [selectedIndex, suggestions.length]);

  // Group suggestions by type (memoized for performance)
  const groupedSuggestions = useMemo(() => {
    const conceptSuggestions = suggestions.filter((s) => s.type === 'concept');
    const fieldSuggestions = suggestions.filter((s) => s.type === 'field');
    return { conceptSuggestions, fieldSuggestions };
  }, [suggestions]);

  // Handle keyboard navigation at the container level
  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    // Let parent handle keyboard events
    e.stopPropagation();
  }, []);

  if (suggestions.length === 0) {
    return null;
  }

  const { conceptSuggestions, fieldSuggestions } = groupedSuggestions;

  return (
    <div
      ref={containerRef}
      className={`fixed z-50 overflow-hidden rounded border border-term-border bg-term-surface shadow-lg ${className}`.trim()}
      style={{
        top: `${position.top}px`,
        left: `${position.left}px`,
        maxHeight: `${maxHeight}px`,
        width: position.width ? `${position.width}px` : undefined,
      }}
      role="listbox"
      aria-label="Formula autocomplete suggestions"
      aria-activedescendant={suggestions.length > 0 ? `autocomplete-option-${selectedIndex}` : undefined}
      onKeyDown={handleKeyDown}
    >
      {/* Screen reader announcement */}
      <div
        role="status"
        aria-live="polite"
        aria-atomic="true"
        className="sr-only"
      >
        {suggestions.length} suggestion{suggestions.length === 1 ? '' : 's'} available
      </div>

      {/* Header */}
      <div className="flex items-center justify-between border-b border-term-border-subtle bg-term-surface px-4 py-2">
        <span className="text-[10px] font-mono uppercase tracking-[0.2em] text-term-text-muted">
          Autocomplete
        </span>
        <span className="text-[10px] font-mono text-term-text-tertiary">
          {suggestions.length} match{suggestions.length === 1 ? '' : 'es'}
        </span>
      </div>

      {/* Suggestions List */}
      <div
        ref={scrollContainerRef}
        className="overflow-y-auto"
        style={{ maxHeight: `${maxHeight - 40}px` }}
      >
        {fieldSuggestions.length > 0 && (
          <div className="border-b border-term-border-subtle">
            <div className="sticky top-0 bg-term-bg px-3 py-1.5 text-[10px] font-mono font-semibold text-term-text-muted uppercase tracking-wider">
              Fields
            </div>
            {fieldSuggestions.map((suggestion, index) => (
              <SuggestionButton
                key={`field-${suggestion.displayText}-${index}`}
                suggestion={suggestion}
                index={index}
                isSelected={index === selectedIndex}
                onSelect={() => onSelect(index)}
                onHover={() => onHover(index)}
                query={query}
              />
            ))}
          </div>
        )}

        {conceptSuggestions.length > 0 && (
          <div>
            <div className="sticky top-0 bg-term-bg px-3 py-1.5 text-[10px] font-mono font-semibold text-term-text-muted uppercase tracking-wider">
              XBRL Concepts
            </div>
            {conceptSuggestions.map((suggestion, index) => (
              <SuggestionButton
                key={`concept-${suggestion.displayText}-${index}`}
                suggestion={suggestion}
                index={fieldSuggestions.length + index}
                isSelected={fieldSuggestions.length + index === selectedIndex}
                onSelect={() => onSelect(fieldSuggestions.length + index)}
                onHover={() => onHover(fieldSuggestions.length + index)}
                query={query}
              />
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

interface SuggestionButtonProps {
  suggestion: SuggestionItem;
  index: number;
  isSelected: boolean;
  onSelect: () => void;
  onHover: () => void;
  query: string;
}

const SuggestionButton: React.FC<SuggestionButtonProps> = ({
  suggestion,
  index,
  isSelected,
  onSelect,
  onHover,
  query,
}) => {
  const handleClick = useCallback(() => {
    onSelect();
  }, [onSelect]);

  const handleMouseEnter = useCallback(() => {
    onHover();
  }, [onHover]);

  return (
    <button
      type="button"
      id={`autocomplete-option-${index}`}
      data-index={index}
      className={`flex w-full flex-col items-start gap-1 border-b border-term-border-subtle px-4 py-2.5 text-left font-mono transition-colors last:border-b-0 ${
        isSelected ? 'bg-info/10' : 'hover:bg-term-surface'
      }`}
      onClick={handleClick}
      onMouseEnter={handleMouseEnter}
      role="option"
      aria-selected={isSelected}
      tabIndex={-1}
    >
      <div className="flex w-full items-center justify-between gap-3">
        <span className={`text-sm ${isSelected ? 'text-term-text' : 'text-info'}`}>
          {highlightMatch(suggestion.displayText, query)}
        </span>
        <span
          className={`rounded-full border px-2 py-0.5 text-[10px] uppercase tracking-[0.16em] ${
            isSelected
              ? 'border-info/50 bg-term-bg text-info'
              : 'border-term-border bg-term-bg text-term-text-tertiary'
          }`}
        >
          {index + 1}
        </span>
      </div>

      {/* Metadata */}
      {suggestion.metadata && (
        <div className="flex items-center gap-2 text-[11px] leading-5 text-term-text-muted">
          {suggestion.type === 'concept' && suggestion.metadata.taxonomy && (
            <>
              <span className="rounded bg-term-surface border border-term-border-subtle px-1.5 py-0.5">
                {suggestion.metadata.taxonomy}
              </span>
              {suggestion.metadata.unitFamily && (
                <span className="text-term-text-tertiary">
                  [{suggestion.metadata.unitFamily.replace(/_/g, '-')}]
                </span>
              )}
            </>
          )}
          {suggestion.type === 'field' && suggestion.metadata.fieldDisplayName && (
            <span className="text-term-text-tertiary">
              {suggestion.metadata.fieldDisplayName}
            </span>
          )}
          {suggestion.type === 'concept' && suggestion.metadata.label && (
            <span className="truncate">{suggestion.metadata.label}</span>
          )}
        </div>
      )}
    </button>
  );
};
