---
import {siteConfig} from "../config";
import { getLangFromUrl, useTranslations, useTranslatedPath } from '../i18n/utils';

const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
const translatePath = useTranslatedPath(lang);
const noscript = siteConfig.noClientJavaScript
const searchEngine = siteConfig.searchEngine || 'google'
const domain = Astro.url.host
---
{noscript ?
<form class="search-container" action={searchEngine === "duckduckgo" ? "https://duckduckgo.com/" :
    searchEngine === "bing" ? "https://www.bing.com/search" :
        "https://www.google.com/search"} method="GET" target="_blank">
  <div>
    <label for="search-input"><span class="command">search</span></label>
    <input name="q" type="text" id="search-input" class="search-input"  autocomplete="off" placeholder={t('search.placeholder')} />
    {searchEngine === "duckduckgo" &&
        <input type="hidden" name="sites" value={domain} />
    }
    {searchEngine === "google" &&
        <input type="hidden" name="as_sitesearch" value={domain} />
    }
    {/* broken until M1cr0$0ft get support for it */}
    {searchEngine === "bing" &&
        <input type="hidden" name="site" value={domain} />
    }
  </div>
  <input type="submit" style="display: none" />
</form>
    :
<div class="search-container">
  <div class="command-prompt">
    <span class="command">search</span>
    <input 
      type="text" 
      id="search-input" 
      class="search-input" 
      placeholder={t('search.placeholder')}
      autocomplete="off"
    />
  </div>
  <div id="search-results" class="search-results"></div>
</div>
<script>
  /*
  ====================================================================

  tweaked from FAST SEARCH —
  https://gist.github.com/cmod/5410eae147e4318164258742dd053993

  ====================================================================
  */
  // Configuration
  const CONFIG = {
    search: {
      minChars: 2,              // Minimum characters before searching
      maxResults: 5,            // Maximum number of results to show
      fields: {                 // Fields to search through
        title: true,            // Allow searching in title
        description: true,      // Allow searching in description
        content: true           // Allow searching in contents
      }
    }
  };

  // Function to initialize search with custom config
  function initSearch(): void {
    // Cache DOM elements
    const searchInput = document.getElementById('search-input') as HTMLInputElement;
    const searchResults = document.getElementById('search-results') as HTMLElement;

    let searchIndex: Array<{
      title: string;
      description?: string;
      slug?: string;
      date?: Date;
      searchableTitle: string;
      searchableDesc: string;
      searchableContent: string;
    }> | null = null;
    let resultsAvailable = false;
    let firstRun = true;

    // Load the search index
    async function loadSearchIndex(): Promise<void> {
      try {
        const response = await fetch('/search-index.json');
        if (!response.ok) throw new Error('Failed to load search index');
        const data = await response.json();

        searchIndex = data.map((item: any) => ({
          ...item,
          searchableTitle: item.title?.toLowerCase() || '',
          searchableDesc: item.description?.toLowerCase() || '',
          searchableContent: (item.content as string)?.toLowerCase() || ''
        }));

        if (searchInput && searchInput.value) {
          performSearch(searchInput.value);
        }
      } catch (error) {
        console.error('Error loading search index:', error);
        if (searchResults) {
          searchResults.innerHTML = '<li class="search-message">Error loading search index...</li>';
        }
      }
    }

    // Simple fuzzy match for single words
    function simpleFuzzyMatch(text: string, term: string): boolean {
      if (text.includes(term)) return true;
      if (term.length < 3) return false;

      let matches = 0;
      let lastMatchIndex = -1;

      for (let i = 0; i < term.length; i++) {
        const found = text.indexOf(term[i], lastMatchIndex + 1);
        if (found > -1) {
          matches++;
          lastMatchIndex = found;
        }
      }

      return matches === term.length;
    }

    function performSearch(term: string): void {
      term = term.toLowerCase().trim();

      if (!term || !searchIndex) {
        searchResults.innerHTML = '';
        resultsAvailable = false;
        return;
      }

      if (term.length < CONFIG.search.minChars) {
        searchResults.innerHTML = '<span class="search-message">Please enter at least 2 characters...</span>';
        resultsAvailable = false;
        return;
      }

      // Split search into terms
      const searchTerms = term.split(/\s+/).filter(t => t.length > 0);

      // Search with scoring
      const results = searchIndex
        .map(item => {
          let score = 0;
          const matchesAllTerms = searchTerms.every(term => {
            let matched = false;

            // Title matches (weighted higher)
            if (CONFIG.search.fields.title) {
              if (item.searchableTitle.startsWith(term)) {
                score += 3;  // Highest score for prefix matches in title
                matched = true;
              } else if (simpleFuzzyMatch(item.searchableTitle, term)) {
                score += 2;  // Good score for fuzzy matches in title
                matched = true;
              }
            }

            // Other field matches
            if (!matched) {
              if (CONFIG.search.fields.description && item.searchableDesc.includes(term)) {
                score += 0.5;  // Lower score for description matches
                matched = true;
              }
              if (CONFIG.search.fields.content && item.searchableContent.includes(term)) {
                score += 0.5;  // Lower score for content matches
                matched = true;
              }
            }

            return matched;
          });

          return {
            item,
            score: matchesAllTerms ? score : 0
          };
        })
        .filter(result => result.score > 0)
        .sort((a, b) => b.score - a.score)
        .slice(0, CONFIG.search.maxResults)
        .map(result => result.item);

      resultsAvailable = results.length > 0;

      if (!resultsAvailable) {
        searchResults.innerHTML = '<span class="search-message">No matching results found...</span>';
        return;
      }

      const searchItems = results.map(item => `
      <div class="search-result">
        <a href="/blog/${item.slug}" tabindex="0">
          <span class="result-title">${item.title}</span><br /> 
          <span class="result-date">${new Date(item.date).toISOString().split('T')[0]|| '' } — 
          <em>${item.description || ''}</em></span>
        </a>
      </div>
      `).join('');

      searchResults.innerHTML = searchItems;
    }

    // Basic HTML escaping for security
    function escapeHtml(unsafe: string): string {
      if (!unsafe) return '';
      return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
    }

    // Add event listener for search input
    if (searchInput) {
      // Load index on focus
      searchInput.addEventListener('focus', function() {
        loadSearchIndex();
      });

      searchInput.addEventListener('input', function() {
        if (!searchIndex && !firstRun) {
          searchResults.innerHTML = '<span class="search-message">Loading search index...</span>';
          return;
        }
        performSearch(this.value);
      });
    }
    firstRun = false;
  }

  // Initialize with default config
  initSearch();

  // Re-initialize when Astro's view transitions occur, this provides fix for SPA navigation
  document.addEventListener('astro:page-load', initSearch);
</script>}

<style>
  .search-container {
    margin: 2rem 0;
  }

  .command-prompt {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .search-input {
    background: transparent;
    border: none;
    color: var(--text-color);
    font-family: var(--font-mono);
    font-size: 1rem;
    padding: 0.5rem;
    outline: none;
  }

  .search-results {
    margin-top: 1rem;
    margin-left: 1rem;
  }

  .search-result {
    margin: 0.5rem 0;
  }

  .search-result a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem;
    text-decoration: none;
    color: var(--text-color);
    border-radius: 4px;
  }

  .search-result a:hover {
    background: var(--border-color);
  }

  .result-date {
    color: var(--terminal-yellow);
    font-size: 0.9rem;
  }
</style>