// src/utils/clientUtils.ts
// Client-side utilities - now only contains AutocompleteManager to avoid duplication
// Other utilities consolidated into globalUtils.ts

import { createToolSlug, findToolByIdentifier, isToolHosted } from './toolHelpers.js';

// Re-export tool helper functions to maintain API compatibility
export { createToolSlug, findToolByIdentifier, isToolHosted };

// Consolidated Autocomplete Functionality - this is unique and not duplicated elsewhere
interface AutocompleteOptions {
  minLength?: number;
  maxResults?: number;
  placeholder?: string;
  allowMultiple?: boolean;
  separator?: string;
  filterFunction?: (query: string) => any[];
  renderFunction?: (item: any) => string;
  hiddenInput?: HTMLInputElement;
}

export class AutocompleteManager {
  public input: HTMLInputElement;
  public dataSource: any[];
  public options: AutocompleteOptions;
  public isOpen: boolean = false;
  public selectedIndex: number = -1;
  public filteredData: any[] = [];
  public selectedItems: Set<string> = new Set();
  public dropdown!: HTMLElement;
  public selectedContainer!: HTMLElement;

  constructor(inputElement: HTMLInputElement, dataSource: any[], options: AutocompleteOptions = {}) {
    this.input = inputElement;
    this.dataSource = dataSource;
    this.options = {
      minLength: 1,
      maxResults: 10,
      placeholder: 'Type to search...',
      allowMultiple: false,
      separator: ', ',
      filterFunction: this.defaultFilter.bind(this),
      renderFunction: this.defaultRender.bind(this),
      ...options
    };
    
    this.init();
  }
  
  init(): void {
    this.createDropdown();
    this.bindEvents();
    
    if (this.options.allowMultiple) {
      this.initMultipleMode();
    }
  }
  
  createDropdown(): void {
    this.dropdown = document.createElement('div');
    this.dropdown.className = 'autocomplete-dropdown';
    this.dropdown.style.cssText = `
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      background: var(--color-bg);
      border: 1px solid var(--color-border);
      border-radius: 0.375rem;
      box-shadow: var(--shadow-lg);
      max-height: 200px;
      overflow-y: auto;
      z-index: 1000;
      display: none;
    `;
    
    // Insert dropdown after input
    const parentElement = this.input.parentNode as HTMLElement;
    parentElement.style.position = 'relative';
    parentElement.insertBefore(this.dropdown, this.input.nextSibling);
  }
  
  bindEvents(): void {
    this.input.addEventListener('input', (e) => {
      this.handleInput((e.target as HTMLInputElement).value);
    });
    
    this.input.addEventListener('keydown', (e) => {
      this.handleKeydown(e);
    });
    
    this.input.addEventListener('focus', () => {
      if (this.input.value.length >= (this.options.minLength || 1)) {
        this.showDropdown();
      }
    });
    
    this.input.addEventListener('blur', () => {
      // Delay to allow click events on dropdown items
      setTimeout(() => {
        const activeElement = document.activeElement;
        if (!activeElement || !this.dropdown.contains(activeElement)) {
          this.hideDropdown();
        }
      }, 150);
    });
    
    document.addEventListener('click', (e) => {
      const target = e.target as Node;
      if (!this.input.contains(target) && !this.dropdown.contains(target)) {
        this.hideDropdown();
      }
    });
  }
  
  initMultipleMode(): void {
    this.selectedContainer = document.createElement('div');
    this.selectedContainer.className = 'autocomplete-selected';
    this.selectedContainer.style.cssText = `
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      margin-bottom: 0.5rem;
      min-height: 1.5rem;
    `;
    
    const parentElement = this.input.parentNode as HTMLElement;
    parentElement.insertBefore(this.selectedContainer, this.input);
    this.updateSelectedDisplay();
  }
  
  handleInput(value: string): void {
    if (value.length >= (this.options.minLength || 1)) {
      this.filteredData = this.options.filterFunction!(value);
      this.selectedIndex = -1;
      this.renderDropdown();
      this.showDropdown();
    } else {
      this.hideDropdown();
    }
  }
  
  handleKeydown(e: KeyboardEvent): void {
    if (!this.isOpen) return;
    
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        this.selectedIndex = Math.min(this.selectedIndex + 1, this.filteredData.length - 1);
        this.updateHighlight();
        break;
        
      case 'ArrowUp':
        e.preventDefault();
        this.selectedIndex = Math.max(this.selectedIndex - 1, -1);
        this.updateHighlight();
        break;
        
      case 'Enter':
        e.preventDefault();
        if (this.selectedIndex >= 0) {
          this.selectItem(this.filteredData[this.selectedIndex]);
        }
        break;
        
      case 'Escape':
        this.hideDropdown();
        break;
    }
  }
  
  defaultFilter(query: string): any[] {
    const searchTerm = query.toLowerCase();
    return this.dataSource
      .filter(item => {
        const text = typeof item === 'string' ? item : item.name || item.label || item.toString();
        return text.toLowerCase().includes(searchTerm) && 
               (!this.options.allowMultiple || !this.selectedItems.has(text));
      })
      .slice(0, this.options.maxResults || 10);
  }
  
  defaultRender(item: any): string {
    const text = typeof item === 'string' ? item : item.name || item.label || item.toString();
    return `<div class="autocomplete-item">${this.escapeHtml(text)}</div>`;
  }
  
  renderDropdown(): void {
    if (this.filteredData.length === 0) {
      this.dropdown.innerHTML = '<div class="autocomplete-no-results">No results found</div>';
      return;
    }
    
    this.dropdown.innerHTML = this.filteredData
      .map((item, index) => {
        const content = this.options.renderFunction!(item);
        return `<div class="autocomplete-option" data-index="${index}" style="
          padding: 0.5rem;
          cursor: pointer;
          border-bottom: 1px solid var(--color-border-light);
          transition: background-color 0.15s ease;
        ">${content}</div>`;
      })
      .join('');
    
    // Bind click events
    this.dropdown.querySelectorAll('.autocomplete-option').forEach((option, index) => {
      option.addEventListener('click', () => {
        this.selectItem(this.filteredData[index]);
      });
      
      option.addEventListener('mouseenter', () => {
        this.selectedIndex = index;
        this.updateHighlight();
      });
    });
  }
  
  updateHighlight(): void {
    this.dropdown.querySelectorAll('.autocomplete-option').forEach((option, index) => {
      (option as HTMLElement).style.backgroundColor = index === this.selectedIndex 
        ? 'var(--color-bg-secondary)' 
        : 'transparent';
    });
  }
  
  selectItem(item: any): void {
    const text = typeof item === 'string' ? item : item.name || item.label || item.toString();
    
    if (this.options.allowMultiple) {
      this.selectedItems.add(text);
      this.updateSelectedDisplay();
      this.updateInputValue();
      this.input.value = '';
    } else {
      this.input.value = text;
      this.hideDropdown();
    }
    
    // Trigger change event
    this.input.dispatchEvent(new CustomEvent('autocomplete:select', {
      detail: { item, text, selectedItems: Array.from(this.selectedItems) }
    }));
  }
  
  removeItem(text: string): void {
    if (this.options.allowMultiple) {
      this.selectedItems.delete(text);
      this.updateSelectedDisplay();
      this.updateInputValue();
    }
  }
  
  updateSelectedDisplay(): void {
    if (!this.options.allowMultiple || !this.selectedContainer) return;
    
    this.selectedContainer.innerHTML = Array.from(this.selectedItems)
      .map(item => `
        <span class="autocomplete-tag" style="
          background-color: var(--color-primary);
          color: white;
          padding: 0.25rem 0.5rem;
          border-radius: 0.25rem;
          font-size: 0.875rem;
          display: flex;
          align-items: center;
          gap: 0.25rem;
        ">
          ${this.escapeHtml(item)}
          <button type="button" class="autocomplete-remove" data-item="${this.escapeHtml(item)}" style="
            background: none;
            border: none;
            color: white;
            font-weight: bold;
            cursor: pointer;
            padding: 0;
            width: 1rem;
            height: 1rem;
            display: flex;
            align-items: center;
            justify-content: center;
          ">×</button>
        </span>
      `)
      .join('');
    
    // Bind remove events
    this.selectedContainer.querySelectorAll('.autocomplete-remove').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.preventDefault();
        this.removeItem((btn as HTMLElement).getAttribute('data-item')!);
      });
    });
  }
  
  updateInputValue(): void {
    if (this.options.allowMultiple && this.options.hiddenInput) {
      this.options.hiddenInput.value = Array.from(this.selectedItems).join(this.options.separator || ', ');
    }
  }
  
  showDropdown(): void {
    this.dropdown.style.display = 'block';
    this.isOpen = true;
  }
  
  hideDropdown(): void {
    this.dropdown.style.display = 'none';
    this.isOpen = false;
    this.selectedIndex = -1;
  }
  
  escapeHtml(text: string): string {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
  
  setDataSource(newDataSource: any[]): void {
    this.dataSource = newDataSource;
  }
  
  getSelectedItems(): string[] {
    return Array.from(this.selectedItems);
  }
  
  setSelectedItems(items: string[]): void {
    this.selectedItems = new Set(items);
    if (this.options.allowMultiple) {
      this.updateSelectedDisplay();
      this.updateInputValue();
    }
  }
  
  destroy(): void {
    if (this.dropdown && this.dropdown.parentNode) {
      this.dropdown.parentNode.removeChild(this.dropdown);
    }
    if (this.selectedContainer && this.selectedContainer.parentNode) {
      this.selectedContainer.parentNode.removeChild(this.selectedContainer);
    }
  }
}