import { updatePanelPositions, showToast } from "../utils/uiHelpers.js";
import { getCurrentPageState } from "../state/index.js";
import { getModelApiClient } from "../api/modelApiFactory.js";
import { setStorageItem, getStorageItem } from "../utils/storageHelpers.js";
/**
 * SearchManager - Handles search functionality across different pages
 * Each page can extend or customize this base functionality
 */
export class SearchManager {
    constructor(options = {}) {
      this.options = {
        searchDelay: 300,
        minSearchLength: 2,
        ...options
      };
      
      this.searchInput = document.getElementById('searchInput');
      this.searchOptionsToggle = document.getElementById('searchOptionsToggle');
      this.searchOptionsPanel = document.getElementById('searchOptionsPanel');
      this.closeSearchOptions = document.getElementById('closeSearchOptions');
      this.searchOptionTags = document.querySelectorAll('.search-option-tag');
      
      this.searchTimeout = null;
      this.currentPage = options.page || document.body.dataset.page || 'loras';
      this.isSearching = false;
      
      // Create clear button for search input
      this.createClearButton();
      
      // Keyboard shortcut cue element (static, exists in the HTML)
      this.searchShortcutCue = document.getElementById('searchShortcutCue');
      
      this.initEventListeners();
      this.loadSearchPreferences();
      this.setupKeyboardShortcuts();
      
      updatePanelPositions();
      
      // Add resize listener
      window.addEventListener('resize', updatePanelPositions);
    }
    
    // Add this new method to setup keyboard shortcuts
    setupKeyboardShortcuts() {
      // Add global keyboard shortcut listener for Ctrl+F or Cmd+F
      document.addEventListener('keydown', (e) => {
        // Check for Ctrl+F (Windows/Linux) or Cmd+F (Mac)
        if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
          // Prevent default browser search behavior
          e.preventDefault();
          
          // Focus the search input if it exists
          if (this.searchInput) {
            this.searchInput.focus();
            
            // Optionally select all text in the search input for easy replacement
            this.searchInput.select();
          }
        }
      });
    }
    
    initEventListeners() {
      // Search input event
      if (this.searchInput) {
        this.searchInput.addEventListener('input', () => {
          clearTimeout(this.searchTimeout);
          this.searchTimeout = setTimeout(() => this.performSearch(), this.options.searchDelay);
          this.updateClearButtonVisibility();
        });
        
        // Clear search with Escape key
        this.searchInput.addEventListener('keydown', (e) => {
          if (e.key === 'Escape') {
            this.searchInput.value = '';
            this.updateClearButtonVisibility();
            this.performSearch();
          }
        });
      }
      
      // Search options toggle
      if (this.searchOptionsToggle) {
        this.searchOptionsToggle.addEventListener('click', () => {
          this.toggleSearchOptionsPanel();
        });
      }
      
      // Close search options
      if (this.closeSearchOptions) {
        this.closeSearchOptions.addEventListener('click', () => {
          this.closeSearchOptionsPanel();
        });
      }
      
      // Search option tags
      if (this.searchOptionTags) {
        this.searchOptionTags.forEach(tag => {
          tag.addEventListener('click', () => {
            // Check if clicking would deselect the last active option
            const activeOptions = document.querySelectorAll('.search-option-tag.active');
            if (activeOptions.length === 1 && activeOptions[0] === tag) {
                showToast('toast.search.atLeastOneOption', {}, 'info');
              return;
            }
            
            tag.classList.toggle('active');
            this.saveSearchPreferences();
            this.performSearch();
          });
        });
      }
      
      // Add global click handler to close panels when clicking outside
      document.addEventListener('click', (e) => {
        // Close search options panel when clicking outside
        if (this.searchOptionsPanel && 
            !this.searchOptionsPanel.contains(e.target) && 
            e.target !== this.searchOptionsToggle &&
            !this.searchOptionsToggle.contains(e.target)) {
          this.closeSearchOptionsPanel();
        }
        
        // Close filter panel when clicking outside (if filterManager exists)
        const filterPanel = document.getElementById('filterPanel');
        const filterButton = document.getElementById('filterButton');
        if (filterPanel && 
            !filterPanel.contains(e.target) && 
            e.target !== filterButton &&
            !filterButton.contains(e.target) &&
            window.filterManager) {
          window.filterManager.closeFilterPanel();
        }
      });
    }
    
    createClearButton() {
      // Create clear button if it doesn't exist
      if (!this.searchInput) return;
      
      // Check if clear button already exists
      let clearButton = this.searchInput.parentNode.querySelector('.search-clear');
      
      if (!clearButton) {
        // Create clear button
        clearButton = document.createElement('button');
        clearButton.className = 'search-clear';
        clearButton.innerHTML = '<i class="fas fa-times"></i>';
        clearButton.title = 'Clear search';
        
        // Add click handler
        clearButton.addEventListener('click', () => {
          this.searchInput.value = '';
          this.updateClearButtonVisibility();
          this.performSearch();
        });
        
        // Insert after search input
        this.searchInput.parentNode.appendChild(clearButton);
      }
      
      this.clearButton = clearButton;
      
      // Set initial visibility
      this.updateClearButtonVisibility();
    }
    
    updateClearButtonVisibility() {
      const hasText = this.searchInput.value.length > 0;
      if (this.clearButton) {
        this.clearButton.classList.toggle('visible', hasText);
      }
      // Toggle the keyboard shortcut cue: visible only when search is empty
      if (this.searchShortcutCue) {
        this.searchShortcutCue.classList.toggle('hidden', hasText);
      }
    }
    
    toggleSearchOptionsPanel() {
      if (this.searchOptionsPanel) {
        const isHidden = this.searchOptionsPanel.classList.contains('hidden');
        if (isHidden) {
          // Update position before showing
          updatePanelPositions();
          this.searchOptionsPanel.classList.remove('hidden');
          this.searchOptionsToggle.classList.add('active');
          
          // Ensure the panel is visible
          this.searchOptionsPanel.style.display = 'block';
        } else {
          this.closeSearchOptionsPanel();
        }
      }
    }
    
    closeSearchOptionsPanel() {
      if (this.searchOptionsPanel) {
        this.searchOptionsPanel.classList.add('hidden');
        this.searchOptionsToggle.classList.remove('active');
      }
    }
    
    loadSearchPreferences() {
      try {
        const preferences = getStorageItem(`${this.currentPage}_search_prefs`) || {};
        
        // Apply search options
        if (preferences.options) {
          this.searchOptionTags.forEach(tag => {
            const option = tag.dataset.option;
            if (preferences.options[option] !== undefined) {
              tag.classList.toggle('active', preferences.options[option]);
            }
          });
        }
        
        // Ensure at least one search option is selected
        this.validateSearchOptions();
      } catch (error) {
        console.error('Error loading search preferences:', error);
        // Set default options if loading fails
        this.setDefaultSearchOptions();
      }
    }
    
    validateSearchOptions() {
      // Check if at least one search option is active
      const hasActiveOption = Array.from(this.searchOptionTags).some(tag => 
        tag.classList.contains('active')
      );
      
      // If no search options are active, activate default options
      if (!hasActiveOption) {
        this.setDefaultSearchOptions();
      }
    }
    
    setDefaultSearchOptions() {
      // Default to filename search option if available
      const filenameOption = Array.from(this.searchOptionTags).find(tag => 
        tag.dataset.option === 'filename'
      );
      
      if (filenameOption) {
        filenameOption.classList.add('active');
      } else if (this.searchOptionTags.length > 0) {
        // Otherwise, select the first option
        this.searchOptionTags[0].classList.add('active');
      }
      
      // Save the default preferences
      this.saveSearchPreferences();
    }
    
    saveSearchPreferences() {
      try {
        const options = {};
        this.searchOptionTags.forEach(tag => {
          options[tag.dataset.option] = tag.classList.contains('active');
        });
        
        const preferences = {
          options
        };
        
        setStorageItem(`${this.currentPage}_search_prefs`, preferences);
      } catch (error) {
        console.error('Error saving search preferences:', error);
      }
    }
    
    getActiveSearchOptions() {
      const options = {};
      this.searchOptionTags.forEach(tag => {
        options[tag.dataset.option] = tag.classList.contains('active');
      });
      return options;
    }
    
    performSearch() {
      const query = this.searchInput.value.trim();
      const options = this.getActiveSearchOptions();
      
      // Update the state with search parameters
      const pageState = getCurrentPageState();
      
      // Set search query in filters
      if (pageState && pageState.filters) {
        pageState.filters.search = query;
      }
      
      // Update search options based on page type
      if (pageState && pageState.searchOptions) {
        if (this.currentPage === 'recipes') {
            // Update only the relevant fields in searchOptions instead of replacing the whole object
            pageState.searchOptions.title = options.title || false;
            pageState.searchOptions.tags = options.tags || false;
            pageState.searchOptions.loraName = options.loraName || false;
            pageState.searchOptions.loraModel = options.loraModel || false;
            pageState.searchOptions.prompt = options.prompt || false;
        } else if (this.currentPage === 'loras' || this.currentPage === 'checkpoints' || this.currentPage === 'embeddings') {
            // Update only the relevant fields in searchOptions instead of replacing the whole object
            pageState.searchOptions.filename = options.filename || false;
            pageState.searchOptions.modelname = options.modelname || false;
            pageState.searchOptions.tags = options.tags || false;
            pageState.searchOptions.creator = options.creator || false;
            pageState.searchOptions.hash = options.hash || false;
        }
      }
      
      // Call the appropriate manager's load method based on page type
      if (this.currentPage === 'recipes' && window.recipeManager) {
        window.recipeManager.loadRecipes(true);
      } else if (this.currentPage === 'loras' || this.currentPage === 'embeddings' || this.currentPage === 'checkpoints') {
        // For models page, reset the page and reload
        getModelApiClient().loadMoreWithVirtualScroll(true, false);
      }
    }
  }