<script lang="ts">
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { getEventsByKind } from '../../services/cache/event-cache.js';
  import ProfileBadge from '../layout/ProfileBadge.svelte';
  import RelayBadge from '../layout/RelayBadge.svelte';
  import CacheBadge from '../layout/CacheBadge.svelte';
  import { getKindInfo, KIND_LOOKUP, isParameterizedReplaceableKind } from '../../types/kind-lookup.js';
  import { nip19 } from 'nostr-tools';
  import { goto } from '$app/navigation';
  import type { NostrEvent } from '../../types/nostr.js';

  let searchQuery = $state('');
  let searching = $state(false);
  let results = $state<Array<{ event: NostrEvent; matchedTag: string; matchedValue: string; relevance: number; relay?: string }>>([]);
  let cacheResults = $state<Array<{ event: NostrEvent; matchedTag: string; matchedValue: string; relevance: number; relay?: string }>>([]);
  let timeoutId: ReturnType<typeof setTimeout> | null = $state(null);
  let cacheSearchTimeoutId: ReturnType<typeof setTimeout> | null = $state(null);

  // Tag search order (by relevance)
  const searchTags = ['d', 'T', 'C', 'title', 'author', 'summary', 'description'];
  const SEARCH_TIMEOUT = 10000; // 10 seconds
  const CACHE_SEARCH_DEBOUNCE = 500; // 500ms debounce for cache search
  
  // Get only the parameterized replaceable kinds that are actually defined (computed once)
  const parameterizedKinds = Object.keys(KIND_LOOKUP)
    .map(Number)
    .filter(kind => isParameterizedReplaceableKind(kind));

  // Map to track results by event ID to avoid duplicates
  const resultsMap = new Map<string, { event: NostrEvent; matchedTag: string; matchedValue: string; relevance: number; relay?: string }>();
  // Map to track cache results by event ID
  const cacheResultsMap = new Map<string, { event: NostrEvent; matchedTag: string; matchedValue: string; relevance: number; relay?: string }>();
  // Map to track which relay each event came from
  const eventRelayMap = new Map<string, string>();

  function scoreEvent(event: NostrEvent, query: string): { tag: string; value: string; relevance: number } | null {
    let bestMatch: { tag: string; value: string; relevance: number } | null = null;

    // Check each tag in order of relevance
    for (let i = 0; i < searchTags.length; i++) {
      const tagName = searchTags[i];
      const relevance = searchTags.length - i; // Higher number = more relevant

      // Check both lowercase and original case tags
      const tagVariants = [tagName, tagName.toLowerCase(), tagName.toUpperCase()];
      
      for (const tagVariant of tagVariants) {
        const tags = event.tags.filter(t => t[0] === tagVariant && t[1]);
        
        for (const tag of tags) {
          const value = tag[1]?.toLowerCase() || '';
          
          // Check if query matches (exact match, contains, or word boundary match)
          if (value === query) {
            // Exact match - highest priority
            if (!bestMatch || bestMatch.relevance < relevance * 10) {
              bestMatch = { tag: tagVariant, value: tag[1] || '', relevance: relevance * 10 };
            }
          } else if (value.includes(query)) {
            // Contains match
            if (!bestMatch || bestMatch.relevance < relevance) {
              bestMatch = { tag: tagVariant, value: tag[1] || '', relevance };
            }
          } else if (query.includes(' ') || query.includes('-')) {
            // For multi-word queries, check if all words are present
            const queryWords = query.split(/[\s-]+/).filter(w => w.length > 0);
            const allWordsMatch = queryWords.every(word => value.includes(word));
            
            if (allWordsMatch && (!bestMatch || bestMatch.relevance < relevance * 0.8)) {
              bestMatch = { tag: tagVariant, value: tag[1] || '', relevance: relevance * 0.8 };
            }
          }
        }
      }
    }

    return bestMatch;
  }

  function addResult(event: NostrEvent, query: string, relay?: string, isCache: boolean = false) {
    const targetMap = isCache ? cacheResultsMap : resultsMap;
    const limit = 100;
    
    // Limit to 100 results total
    if (targetMap.size >= limit) {
      return;
    }
    
    const bestMatch = scoreEvent(event, query);
    if (bestMatch) {
      // Track relay source
      if (relay) {
        eventRelayMap.set(event.id, relay);
      }
      
      const result = {
        event,
        matchedTag: bestMatch.tag,
        matchedValue: bestMatch.value,
        relevance: bestMatch.relevance,
        relay: relay || (isCache ? 'cache' : eventRelayMap.get(event.id))
      };
      
      // Update or add result
      targetMap.set(event.id, result);
      
      // Update results array (sorted by relevance, limit to 100)
      if (isCache) {
        cacheResults = Array.from(cacheResultsMap.values())
          .sort((a, b) => b.relevance - a.relevance)
          .slice(0, limit);
      } else {
        results = Array.from(resultsMap.values())
          .sort((a, b) => b.relevance - a.relevance)
          .slice(0, limit);
      }
    }
  }

  // Search cache only (debounced)
  async function searchCache() {
    if (!searchQuery.trim()) {
      cacheResults = [];
      cacheResultsMap.clear();
      return;
    }

    const query = searchQuery.trim();
    cacheResults = [];
    cacheResultsMap.clear();

    try {
      // Check if it's an naddr
      if (/^naddr1[a-z0-9]+$/i.test(query)) {
        try {
          const decoded = nip19.decode(query);
          if (decoded.type === 'naddr' && decoded.data && typeof decoded.data === 'object' && 'kind' in decoded.data && 'pubkey' in decoded.data && 'identifier' in decoded.data) {
            const naddrData = decoded.data as { kind: number; pubkey: string; identifier: string };
            const kind = naddrData.kind;
            const pubkey = String(naddrData.pubkey);
            const dTag = String(naddrData.identifier);
            
            // Search cache for event with matching kind, pubkey, and d tag
            const cachedByKind = await getEventsByKind(kind, 1000);
            const event = cachedByKind.find(e => 
              e.pubkey.toLowerCase() === pubkey.toLowerCase() && 
              e.tags.some(t => t[0] === 'd' && t[1] === dTag)
            );
            
            if (event) {
              addResult(event, dTag, 'cache', true);
              return;
            }
          }
        } catch {
          // Not a valid naddr, continue with regular search
        }
      }

      const queryLower = query.toLowerCase();

      // Get all cached events for these kinds
      const allCachedEvents: NostrEvent[] = [];
      for (const kind of parameterizedKinds) {
        const cached = await getEventsByKind(kind, 1000); // Get up to 1000 per kind
        allCachedEvents.push(...cached);
      }

      // Filter and score events
      for (const event of allCachedEvents) {
        if (cacheResultsMap.size < 100) {
          addResult(event, queryLower, 'cache', true);
        }
      }
    } catch (error) {
      console.error('Error searching cache:', error);
    }
  }

  // Debounced cache search
  let isSearchingCache = $state(false);
  
  $effect(() => {
    // Only react to searchQuery changes, not cacheResults
    const query = searchQuery.trim();
    
    // Clear previous timeout
    if (cacheSearchTimeoutId) {
      clearTimeout(cacheSearchTimeoutId);
      cacheSearchTimeoutId = null;
    }

    if (query) {
      cacheSearchTimeoutId = setTimeout(() => {
        if (!isSearchingCache) {
          isSearchingCache = true;
          searchCache().finally(() => {
            isSearchingCache = false;
          });
        }
      }, CACHE_SEARCH_DEBOUNCE);
    } else {
      // Only clear if we're not currently searching
      if (!isSearchingCache) {
        cacheResults = [];
        cacheResultsMap.clear();
      }
    }

    return () => {
      if (cacheSearchTimeoutId) {
        clearTimeout(cacheSearchTimeoutId);
        cacheSearchTimeoutId = null;
      }
    };
  });

  async function search() {
    if (!searchQuery.trim()) {
      results = [];
      resultsMap.clear();
      return;
    }

    // Clear previous timeout
    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = null;
    }

    searching = true;
    results = [];
    resultsMap.clear();
    eventRelayMap.clear();

    const query = searchQuery.trim();
    
    // Set timeout
    timeoutId = setTimeout(() => {
      searching = false;
      timeoutId = null;
    }, SEARCH_TIMEOUT);

    try {
      // Check if it's an naddr
      if (/^naddr1[a-z0-9]+$/i.test(query)) {
        try {
          const decoded = nip19.decode(query);
          if (decoded.type === 'naddr' && decoded.data && typeof decoded.data === 'object' && 'kind' in decoded.data && 'pubkey' in decoded.data && 'identifier' in decoded.data) {
            const naddrData = decoded.data as { kind: number; pubkey: string; identifier: string; relays?: string[] };
            const kind = naddrData.kind;
            const pubkey = String(naddrData.pubkey);
            const dTag = String(naddrData.identifier);
            
            // Use relay hints from naddr if available, otherwise use default relays
            const relays = naddrData.relays && naddrData.relays.length > 0
              ? naddrData.relays
              : relayManager.getProfileReadRelays();
            
            // Fetch the specific event
            const events = await nostrClient.fetchEvents(
              [{ kinds: [kind], authors: [pubkey], '#d': [dTag], limit: 1 }],
              relays,
              { useCache: 'cache-first', cacheResults: true, timeout: SEARCH_TIMEOUT }
            );
            
            if (events.length > 0) {
              const event = events[0];
              addResult(event, dTag, relays[0] || 'cache');
              // Clear timeout
              if (timeoutId) {
                clearTimeout(timeoutId);
                timeoutId = null;
              }
              searching = false;
              return;
            }
          }
        } catch {
          // Not a valid naddr, continue with regular search
        }
      }

      const queryLower = query.toLowerCase();
      // Normalize query: remove spaces, handle hyphens
      const normalizedQuery = queryLower.replace(/\s+/g, '-');
      const queryWords = queryLower.split(/[\s-]+/).filter(w => w.length > 0);
      
      const relays = relayManager.getProfileReadRelays();
      
      const allQueries: any[] = [];
      
      // Build queries with tag filters for better search results
      // Only query the specific parameterized replaceable kinds we know about
      
      // Search by d-tag (most specific) - try both original and normalized
      // Also try each word as a potential d-tag match
      allQueries.push(
        { kinds: parameterizedKinds, '#d': [queryLower], limit: 50 },
        { kinds: parameterizedKinds, '#d': [normalizedQuery], limit: 50 }
      );
      for (const word of queryWords) {
        if (word.length > 2) { // Only search for words longer than 2 chars
          allQueries.push({ kinds: parameterizedKinds, '#d': [word], limit: 50 });
        }
      }
      
      // Search by T-tag (topics/tags) for each word
      for (const word of queryWords) {
        if (word.length > 0) {
          allQueries.push({ kinds: parameterizedKinds, '#T': [word], limit: 50 });
        }
      }
      
      // Search by C-tag (categories) for each word
      for (const word of queryWords) {
        if (word.length > 0) {
          allQueries.push({ kinds: parameterizedKinds, '#C': [word], limit: 50 });
        }
      }
      
      // Search by title tag
      allQueries.push({ kinds: parameterizedKinds, '#title': [queryLower], limit: 50 });
      for (const word of queryWords) {
        if (word.length > 0) {
          allQueries.push({ kinds: parameterizedKinds, '#title': [word], limit: 50 });
        }
      }
      
      // Also do a broader search without tag filters to catch partial matches
      // This will find events where the query appears in d-tag but not as exact match
      allQueries.push({ kinds: parameterizedKinds, limit: 200 });
      
      // Use onUpdateWithRelay to process events as they arrive with relay info
      await nostrClient.fetchEvents(
        allQueries,
        relays,
        { 
          useCache: 'cache-first', 
          cacheResults: true,
          timeout: SEARCH_TIMEOUT,
          onUpdateWithRelay: (eventsWithRelay: Array<{ event: NostrEvent; relay: string }>) => {
            // Process events incrementally as they arrive (limit to 100 total)
            for (const { event, relay } of eventsWithRelay) {
              if (!resultsMap.has(event.id) && resultsMap.size < 100) {
                addResult(event, queryLower, relay);
              }
            }
          }
        }
      );

      // Clear timeout if fetch completes before timeout
      if (timeoutId) {
        clearTimeout(timeoutId);
        timeoutId = null;
      }
    } catch (error) {
      console.error('Error searching addressable events:', error);
    } finally {
      searching = false;
    }
  }


  function getTagValue(event: NostrEvent, tagName: string): string | null {
    const tagVariants = [tagName, tagName.toLowerCase(), tagName.toUpperCase()];
    for (const variant of tagVariants) {
      const tag = event.tags.find(t => t[0] === variant && t[1]);
      if (tag && tag[1]) {
        return tag[1];
      }
    }
    return null;
  }

  function getAllTagValues(event: NostrEvent, tagName: string): string[] {
    const tagVariants = [tagName, tagName.toLowerCase(), tagName.toUpperCase()];
    const values: string[] = [];
    for (const variant of tagVariants) {
      const tags = event.tags.filter(t => t[0] === variant && t[1]);
      for (const tag of tags) {
        if (tag[1] && !values.includes(tag[1])) {
          values.push(tag[1]);
        }
      }
    }
    return values;
  }

  function getImageTag(event: NostrEvent): string | null {
    const imageTag = event.tags.find(t => t[0] === 'image' && t[1]);
    return imageTag?.[1] || null;
  }

  function handleResultClick(event: NostrEvent) {
    const dTag = getTagValue(event, 'd');
    if (dTag) {
      // Navigate to /replaceable/[d_tag] route
      goto(`/replaceable/${encodeURIComponent(dTag)}`);
    }
  }

  function handleResultKeydown(e: KeyboardEvent, event: NostrEvent) {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handleResultClick(event);
    }
  }

  function highlightText(text: string, query: string, isMatch: boolean): string {
    if (!isMatch || !query) return text;
    
    const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
    return text.replace(regex, '<mark>$1</mark>');
  }

  export function clearSearch() {
    searchQuery = '';
    results = [];
    cacheResults = [];
    resultsMap.clear();
    cacheResultsMap.clear();
    searching = false;
    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = null;
    }
    if (cacheSearchTimeoutId) {
      clearTimeout(cacheSearchTimeoutId);
      cacheSearchTimeoutId = null;
    }
  }

  export function hasActiveSearch(): boolean {
    return searching || searchQuery.trim().length > 0 || results.length > 0 || cacheResults.length > 0;
  }
</script>

<div class="addressable-search">
  <h2>Search Addressable Events</h2>
  <p class="section-description">
    Search through parameterized events with d-tags, such as long-form articles, wiki pages, or e-books/publications
  </p>
  
  <div class="search-container">
    <div class="search-bar-wrapper">
      <input
        type="text"
        bind:value={searchQuery}
        placeholder="e.g., jane eyre, jane-eyre, Charlotte Bronte..."
        class="search-input"
        disabled={searching}
      />
    </div>
    <div class="filter-and-button-wrapper">
      <div style="flex: 1;"></div>
      <button 
        class="search-button"
        onclick={search}
        disabled={searching || !searchQuery.trim()}
      >
        {searching ? 'Searching...' : 'Search'}
      </button>
    </div>
  </div>

  {#if cacheResults.length > 0 || results.length > 0}
    <div class="results-container">
      {#if cacheResults.length > 0}
        <h3>Found in Cache: ({cacheResults.length})</h3>
        <div class="results-grid">
          {#each cacheResults as { event, matchedTag, matchedValue, relevance, relay }}
            <div 
              class="result-card" 
              role="button"
              tabindex="0"
              onclick={() => handleResultClick(event)}
              onkeydown={(e) => handleResultKeydown(e, event)}
            >
              {#if getImageTag(event)}
                <div class="card-image">
                  <img src={getImageTag(event)} alt="" onerror={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }} />
                </div>
              {/if}
              
              <div class="card-content">
                <div class="card-header">
                  <div class="card-header-left">
                    <ProfileBadge pubkey={event.pubkey} inline={true} />
                    <CacheBadge />
                  </div>
                  <span class="kind-label">{getKindInfo(event.kind).description}</span>
                </div>

                <div class="card-metadata">
                  {#if getTagValue(event, 'd')}
                    <div class="metadata-item">
                      <strong class="metadata-label">d:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'd'}>
                        {@html highlightText(getTagValue(event, 'd') || '', searchQuery, matchedTag.toLowerCase() === 'd')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'T')}
                    <div class="metadata-item">
                      <strong class="metadata-label">T:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag === 'T'}>
                        {@html highlightText(getTagValue(event, 'T') || '', searchQuery, matchedTag === 'T')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'C')}
                    <div class="metadata-item">
                      <strong class="metadata-label">C:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag === 'C'}>
                        {@html highlightText(getTagValue(event, 'C') || '', searchQuery, matchedTag === 'C')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'title')}
                    <div class="metadata-item">
                      <strong class="metadata-label">title:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'title'}>
                        {@html highlightText(getTagValue(event, 'title') || '', searchQuery, matchedTag.toLowerCase() === 'title')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'author')}
                    <div class="metadata-item">
                      <strong class="metadata-label">author:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'author'}>
                        {@html highlightText(getTagValue(event, 'author') || '', searchQuery, matchedTag.toLowerCase() === 'author')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'summary')}
                    <div class="metadata-item">
                      <strong class="metadata-label">summary:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'summary'}>
                        {@html highlightText(getTagValue(event, 'summary') || '', searchQuery, matchedTag.toLowerCase() === 'summary')}
                      </span>
                    </div>
                  {/if}

                  {#if getTagValue(event, 'description')}
                    <div class="metadata-item">
                      <strong class="metadata-label">description:</strong>
                      <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'description'}>
                        {@html highlightText(getTagValue(event, 'description') || '', searchQuery, matchedTag.toLowerCase() === 'description')}
                      </span>
                    </div>
                  {/if}
                </div>

                <div class="card-footer">
                  <code class="event-id">{event.id}</code>
                </div>
              </div>
            </div>
          {/each}
        </div>
      {/if}
      
      {#if results.length > 0}
        <h3>Results from Relays ({results.length})</h3>
        <div class="results-grid">
        {#each results as { event, matchedTag, matchedValue, relevance, relay }}
          <div 
            class="result-card" 
            role="button"
            tabindex="0"
            onclick={() => handleResultClick(event)}
            onkeydown={(e) => handleResultKeydown(e, event)}
          >
            {#if getImageTag(event)}
              <div class="card-image">
                <img src={getImageTag(event)} alt="" onerror={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }} />
              </div>
            {/if}
            
            <div class="card-content">
              <div class="card-header">
                <div class="card-header-left">
                  <ProfileBadge pubkey={event.pubkey} inline={true} />
                  {#if relay}
                    {#if relay === 'cache'}
                      <CacheBadge />
                    {:else}
                      <RelayBadge relayUrl={relay} />
                    {/if}
                  {/if}
                </div>
                <span class="kind-label">{getKindInfo(event.kind).description}</span>
              </div>

              <div class="card-metadata">
                {#if getTagValue(event, 'd')}
                  <div class="metadata-item">
                    <strong class="metadata-label">d:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'd'}>
                      {@html highlightText(getTagValue(event, 'd') || '', searchQuery, matchedTag.toLowerCase() === 'd')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'T')}
                  <div class="metadata-item">
                    <strong class="metadata-label">T:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag === 'T'}>
                      {@html highlightText(getTagValue(event, 'T') || '', searchQuery, matchedTag === 'T')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'C')}
                  <div class="metadata-item">
                    <strong class="metadata-label">C:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag === 'C'}>
                      {@html highlightText(getTagValue(event, 'C') || '', searchQuery, matchedTag === 'C')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'title')}
                  <div class="metadata-item">
                    <strong class="metadata-label">title:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'title'}>
                      {@html highlightText(getTagValue(event, 'title') || '', searchQuery, matchedTag.toLowerCase() === 'title')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'author')}
                  <div class="metadata-item">
                    <strong class="metadata-label">author:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'author'}>
                      {@html highlightText(getTagValue(event, 'author') || '', searchQuery, matchedTag.toLowerCase() === 'author')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'summary')}
                  <div class="metadata-item">
                    <strong class="metadata-label">summary:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'summary'}>
                      {@html highlightText(getTagValue(event, 'summary') || '', searchQuery, matchedTag.toLowerCase() === 'summary')}
                    </span>
                  </div>
                {/if}

                {#if getTagValue(event, 'description')}
                  <div class="metadata-item">
                    <strong class="metadata-label">description:</strong>
                    <span class="metadata-value" class:highlighted={matchedTag.toLowerCase() === 'description'}>
                      {@html highlightText(getTagValue(event, 'description') || '', searchQuery, matchedTag.toLowerCase() === 'description')}
                    </span>
                  </div>
                {/if}
              </div>

              <div class="card-footer">
                <code class="event-id">{event.id}</code>
              </div>
            </div>
          </div>
        {/each}
        </div>
      {/if}
    </div>
  {:else if !searching && searchQuery.trim() && cacheResults.length === 0}
    <div class="no-results">
      No addressable events found matching "{searchQuery}"
    </div>
  {/if}
</div>

<style>
  .addressable-search {
    /* No container styling - parent .find-section handles it */
  }

  .addressable-search h2 {
    margin: 0 0 1.5rem 0;
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--fog-text, #475569);
  }

  :global(.dark) .addressable-search h2 {
    color: var(--fog-dark-text, #cbd5e1);
  }

  .section-description {
    margin: 0 0 1.5rem 0;
    color: var(--fog-text-light, #52667a);
    font-size: 0.875rem;
  }

  :global(.dark) .section-description {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .search-container {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .search-bar-wrapper {
    width: 100%;
  }

  .filter-and-button-wrapper {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  @media (min-width: 640px) {
    .filter-and-button-wrapper {
      flex-direction: row;
      align-items: flex-end;
    }
  }

  .search-input {
    width: 100%;
    padding: 0.75rem 1rem;
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.375rem;
    background: var(--fog-post, #ffffff);
    color: var(--fog-text, #1f2937);
    font-size: 0.875rem;
    font-family: inherit;
  }

  .search-input::placeholder {
    color: var(--fog-text-light, #52667a);
  }

  :global(.dark) .search-input {
    border-color: var(--fog-dark-border, #374151);
    background: var(--fog-dark-post, #1f2937);
    color: var(--fog-dark-text, #f9fafb);
  }

  :global(.dark) .search-input::placeholder {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .search-input:focus {
    outline: none;
    border-color: var(--fog-accent, #64748b);
    box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.1);
  }

  :global(.dark) .search-input:focus {
    border-color: var(--fog-dark-accent, #94a3b8);
    box-shadow: 0 0 0 3px rgba(148, 163, 184, 0.1);
  }

  .search-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .search-button {
    padding: 0.75rem 1.5rem;
    background: var(--fog-accent, #64748b);
    color: #ffffff;
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: 500;
    font-family: inherit;
    white-space: nowrap;
    transition: all 0.2s;
    min-width: 100px;
  }

  @media (min-width: 640px) {
    .search-button {
      min-width: auto;
    }
  }

  :global(.dark) .search-button {
    background: var(--fog-dark-accent, #94a3b8);
    color: #1f2937;
  }

  .search-button:hover:not(:disabled) {
    opacity: 0.9;
    transform: translateY(-1px);
  }

  .search-button:active:not(:disabled) {
    transform: translateY(0);
  }

  .search-button:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .results-container {
    margin-top: 2rem;
  }

  .results-container h3 {
    margin: 0 0 1.5rem 0;
    font-size: 1rem;
    font-weight: 500;
    color: var(--fog-text-light, #52667a);
  }

  :global(.dark) .results-container h3 {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .results-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.5rem;
  }

  .result-card {
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.5rem;
    background: var(--fog-post, #ffffff);
    overflow: hidden;
    cursor: pointer;
    transition: all 0.2s;
  }

  :global(.dark) .result-card {
    border-color: var(--fog-dark-border, #374151);
    background: var(--fog-dark-post, #1f2937);
  }

  .result-card:hover {
    border-color: var(--fog-accent, #64748b);
    transform: translateY(-2px);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  }

  :global(.dark) .result-card:hover {
    border-color: var(--fog-dark-accent, #94a3b8);
  }

  .card-image {
    width: 100%;
    height: 200px;
    overflow: hidden;
    background: var(--fog-highlight, #f3f4f6);
  }

  :global(.dark) .card-image {
    background: var(--fog-dark-highlight, #374151);
  }

  .card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .card-content {
    padding: 1rem;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    gap: 0.5rem;
  }

  .card-header-left {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
  }

  .kind-label {
    font-size: 0.75rem;
    color: var(--fog-text-light, #52667a);
    padding: 0.25rem 0.5rem;
    background: var(--fog-highlight, #f3f4f6);
    border-radius: 0.25rem;
  }

  :global(.dark) .kind-label {
    color: var(--fog-dark-text-light, #a8b8d0);
    background: var(--fog-dark-highlight, #374151);
  }

  .card-metadata {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
  }

  .metadata-item {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
  }

  .metadata-label {
    font-size: 0.75rem;
    color: var(--fog-text-light, #52667a);
    font-weight: 600;
    text-transform: uppercase;
  }

  :global(.dark) .metadata-label {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .metadata-value {
    font-size: 0.875rem;
    color: var(--fog-text, #1f2937);
    word-wrap: break-word;
  }

  :global(.dark) .metadata-value {
    color: var(--fog-dark-text, #f9fafb);
  }

  .metadata-value.highlighted {
    background: var(--fog-accent-light, #e2e8f0);
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
    font-weight: 500;
  }

  :global(.dark) .metadata-value.highlighted {
    background: var(--fog-dark-accent-light, #475569);
  }

  .metadata-value :global(mark) {
    background: var(--fog-accent, #64748b);
    color: white;
    padding: 0.125rem 0.25rem;
    border-radius: 0.125rem;
  }

  :global(.dark) .metadata-value :global(mark) {
    background: var(--fog-dark-accent, #94a3b8);
    color: var(--fog-dark-text, #1f2937);
  }

  .card-footer {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--fog-border, #e5e7eb);
  }

  :global(.dark) .card-footer {
    border-color: var(--fog-dark-border, #374151);
  }

  .event-id {
    font-size: 0.75rem;
    color: var(--fog-text-light, #52667a);
    font-family: monospace;
    word-break: break-all;
  }

  :global(.dark) .event-id {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .no-results {
    padding: 2rem;
    text-align: center;
    color: var(--fog-text-light, #52667a);
    font-size: 0.875rem;
  }

  :global(.dark) .no-results {
    color: var(--fog-dark-text-light, #a8b8d0);
  }
</style>
