<script lang="ts">
  import { sessionManager } from '../../services/auth/session-manager.js';
  import { signAndPublish } from '../../services/nostr/auth-handler.js';
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { config } from '../../services/nostr/config.js';
  import { onMount } from 'svelte';
  import type { NostrEvent } from '../../types/nostr.js';
  import { KIND } from '../../types/kind-lookup.js';
  import { resolveCustomEmojis, fetchEmojiSet, resolveEmojiShortcode } from '../../services/nostr/nip30-emoji.js';
  import EmojiPicker from '../../components/content/EmojiPicker.svelte';
  import emojiData from 'unicode-emoji-json/data-ordered-emoji.json';
  import { shouldIncludeClientTag } from '../../services/client-tag-preference.js';
  import Icon from '../../components/ui/Icon.svelte';
  import { getCachedReactionsForEvents } from '../../services/cache/event-cache.js';
  import PublicationStatusModal from '../../components/modals/PublicationStatusModal.svelte';
  import ProfileBadge from '../../components/layout/ProfileBadge.svelte';

  interface Props {
    event: NostrEvent;
    preloadedReactions?: NostrEvent[]; // Optional pre-loaded reactions to avoid duplicate fetches
  }

  let { event, preloadedReactions }: Props = $props();

  let reactions = $state<Map<string, { content: string; pubkeys: Set<string>; eventIds: Map<string, string> }>>(new Map());
  let userReaction = $state<string | null>(null);
  let userReactionEventId = $state<string | null>(null); // Track the event ID of user's reaction
  let loading = $state(true);
  let showMenu = $state(false);
  let menuButton: HTMLButtonElement | null = $state(null);
  let customEmojiUrls = $state<Map<string, string>>(new Map());
  let allReactionsMap = $state<Map<string, NostrEvent>>(new Map()); // Persist reactions map for real-time updates
  
  let heartCount = $derived(getReactionCount('+'));

  let loadingReactions = $state(false);
  let lastEventId = $state<string | null>(null);
  let isMounted = $state(false);
  let processingUpdate = $state(false);
  let updateDebounceTimer: ReturnType<typeof setTimeout> | null = null;
  let publicationModalOpen = $state(false);
  let publicationResults = $state<{ success: string[]; failed: Array<{ relay: string; error: string }> } | null>(null);
  let hoveredReaction = $state<string | null>(null);
  let hoveredReactionElement = $state<HTMLElement | null>(null);
  let tooltipPosition = $state<{ top: number; left: number } | null>(null);

  onMount(() => {
    // Set lastEventId immediately to prevent $effect from running during mount
    if (event.id) {
      lastEventId = event.id;
    }
    isMounted = true;
    
    // Load from cache IMMEDIATELY (no waiting for initialization)
    if (event.id) {
      // Use pre-loaded reactions if available
      if (preloadedReactions && preloadedReactions.length > 0) {
        for (const r of preloadedReactions) {
          allReactionsMap.set(r.id, r);
        }
        filterDeletedReactions(preloadedReactions).then(filtered => {
          processReactions(filtered);
          loading = false;
        }).catch(() => {
          loading = false;
        });
      } else {
        // Load from cache immediately
        loadFromCache();
      }
    } else {
      loading = false;
    }
    
    // Initialize client in background for relay fetching
    nostrClient.initialize().catch(() => {
      // Silently fail - cache is already loaded
    });
  });

  // Load reactions from cache immediately (synchronous cache access)
  async function loadFromCache() {
    if (!event.id) return;
    
    try {
      // Load from cache FIRST - instant display
      const cachedReactionsMap = await getCachedReactionsForEvents([event.id]);
      const cachedReactions = cachedReactionsMap.get(event.id) || [];
      
      if (cachedReactions.length > 0) {
        // Process cached reactions immediately
        for (const r of cachedReactions) {
          allReactionsMap.set(r.id, r);
        }
        const filtered = await filterDeletedReactions(cachedReactions);
        processReactions(filtered);
        loading = false; // Show cached results immediately
      } else {
        // No cache, need to fetch
        loading = false; // Don't show loading spinner if we have no cache
      }
      
      // Fetch from relays in background (non-blocking)
      loadReactions().catch(() => {
        // Silently fail - we already have cache
      });
    } catch (error) {
      // Cache load failed, try fetching
      loading = false;
      loadReactions().catch(() => {
        // Silently fail
      });
    }
  }

  // Reload reactions when event changes (but prevent duplicate loads and initial mount)
  $effect(() => {
    // Only run after mount and when event.id actually changes
    if (!isMounted || !event.id || event.id === lastEventId || loadingReactions) {
      return;
    }
    
    lastEventId = event.id;
    // Clear previous reactions map when event changes
    allReactionsMap.clear();
    
    // Use pre-loaded reactions if available
    if (preloadedReactions && preloadedReactions.length > 0) {
      for (const r of preloadedReactions) {
        allReactionsMap.set(r.id, r);
      }
      filterDeletedReactions(preloadedReactions).then(filtered => {
        processReactions(filtered);
        loading = false;
      }).catch(() => {
        loading = false;
      });
    } else {
      // Load from cache immediately, then fetch from relays
      loadFromCache();
    }
  });

  // Handle real-time updates - process reactions when new ones arrive
  // Debounced to prevent excessive processing
  async function handleReactionUpdate(updated: NostrEvent[]) {
    // Prevent concurrent processing
    if (processingUpdate) {
      return;
    }
    
    // Add new reactions to the map
    let hasNewReactions = false;
    for (const r of updated) {
      if (!allReactionsMap.has(r.id)) {
        allReactionsMap.set(r.id, r);
        hasNewReactions = true;
      }
    }
    
    // Only process if we have new reactions
    if (!hasNewReactions) {
      return;
    }
    
    // Clear existing debounce timer
    if (updateDebounceTimer) {
      clearTimeout(updateDebounceTimer);
    }
    
    // Debounce processing to batch multiple rapid updates
    updateDebounceTimer = setTimeout(async () => {
      if (processingUpdate) return;
      processingUpdate = true;
      
      try {
        // Process all accumulated reactions
        const allReactions = Array.from(allReactionsMap.values());
        const filtered = await filterDeletedReactions(allReactions);
        processReactions(filtered);
      } finally {
        processingUpdate = false;
      }
    }, 300); // 300ms debounce
  }

  async function loadReactions() {
    // Skip loading if we already have preloaded reactions
    if (preloadedReactions && preloadedReactions.length > 0) {
      // Preloaded reactions are already processed in onMount/$effect
      return;
    }
    
    // Prevent concurrent loads for the same event
    if (loadingReactions) {
      return;
    }
    loadingReactions = true;
    loading = true;
    try {
      // Use getProfileReadRelays() to include defaultRelays + profileRelays + user inbox + localRelays
      // This ensures we get all reactions from the complete relay set, matching DiscussionList behavior
      const reactionRelays = relayManager.getProfileReadRelays();
      
      // Clear and rebuild reactions map for this event
      allReactionsMap.clear();
      
      // Use low priority for reactions - they're background data, comments should load first
      // Use cache-first and shorter timeout for faster loading
      const reactionsWithLowerE = await nostrClient.fetchEvents(
        [{ kinds: [KIND.REACTION], '#e': [event.id], limit: config.feedLimit }],
        reactionRelays,
        { useCache: 'cache-first', cacheResults: true, onUpdate: handleReactionUpdate, timeout: config.shortTimeout, priority: 'low' }
      );
      const reactionsWithUpperE = await nostrClient.fetchEvents(
        [{ kinds: [KIND.REACTION], '#E': [event.id], limit: config.feedLimit }],
        reactionRelays,
        { useCache: 'cache-first', cacheResults: true, onUpdate: handleReactionUpdate, timeout: config.shortTimeout, priority: 'low' }
      );
      
      // Combine and deduplicate by reaction ID
      for (const r of reactionsWithLowerE) {
        allReactionsMap.set(r.id, r);
      }
      for (const r of reactionsWithUpperE) {
        allReactionsMap.set(r.id, r);
      }
      const reactionEvents = Array.from(allReactionsMap.values());
      
      // Filter out deleted reactions (kind 5)
      const filteredReactions = await filterDeletedReactions(reactionEvents);
      
      processReactions(filteredReactions);
    } catch (error) {
      console.error('[FeedReactionButtons] Error loading reactions:', error);
    } finally {
      loading = false;
      loadingReactions = false;
    }
  }

  // Cache of checked reaction IDs to avoid repeated deletion checks
  const checkedReactionIds = new Set<string>();

  async function filterDeletedReactions(reactions: NostrEvent[]): Promise<NostrEvent[]> {
    if (reactions.length === 0) return reactions;
    
    // Filter out reactions we've already checked and found to be non-deleted
    const uncheckedReactions = reactions.filter(r => !checkedReactionIds.has(r.id));
    
    // If all reactions have been checked, return as-is (they're all non-deleted)
    if (uncheckedReactions.length === 0) {
      return reactions;
    }
    
    // Optimize: Instead of fetching all deletion events for all users,
    // fetch deletion events that reference the specific reaction IDs we have
    // This is much more efficient and limits memory usage
    const reactionRelays = relayManager.getProfileReadRelays();
    const reactionIds = uncheckedReactions.map(r => r.id);
    
    // Limit to first 100 reactions to avoid massive queries
    const limitedReactionIds = reactionIds.slice(0, 100);
    
    // Fetch deletion events that reference these specific reaction IDs
    // This is much more efficient than fetching all deletion events from all users
    // Use low priority for deletion events - background data
    const deletionEvents = await nostrClient.fetchEvents(
      [{ kinds: [KIND.EVENT_DELETION], '#e': limitedReactionIds, limit: config.feedLimit }],
      reactionRelays,
      { useCache: true, timeout: config.mediumTimeout, priority: 'low' }
    );
    
    // Build a set of deleted reaction event IDs (more efficient - just a Set)
    const deletedReactionIds = new Set<string>();
    for (const deletionEvent of deletionEvents) {
      // Kind 5 events have 'e' tags pointing to deleted events
      for (const tag of deletionEvent.tags) {
        if (tag[0] === 'e' && tag[1]) {
          deletedReactionIds.add(tag[1]);
        }
      }
    }
    
    // Filter out deleted reactions and mark non-deleted ones as checked
    const filtered = reactions.filter(reaction => {
      const isDeleted = deletedReactionIds.has(reaction.id);
      if (!isDeleted) {
        // Cache that this reaction is not deleted
        checkedReactionIds.add(reaction.id);
      }
      return !isDeleted;
    });
    
    return filtered;
  }

  async function processReactions(reactionEvents: NostrEvent[]) {
    // Prevent duplicate processing - check if we're already processing the same set
    if (processingUpdate) {
      return;
    }
    const reactionMap = new Map<string, { content: string; pubkeys: Set<string>; eventIds: Map<string, string> }>();
    const currentUser = sessionManager.getCurrentPubkey();
    let skippedInvalid = 0;

    for (const reactionEvent of reactionEvents) {
      let content = reactionEvent.content.trim();
      const originalContent = content;
      
      if (!reactionMap.has(content)) {
        reactionMap.set(content, { content, pubkeys: new Set(), eventIds: new Map() });
      }
      reactionMap.get(content)!.pubkeys.add(reactionEvent.pubkey);
      reactionMap.get(content)!.eventIds.set(reactionEvent.pubkey, reactionEvent.id);

      if (currentUser && reactionEvent.pubkey === currentUser) {
        userReaction = content;
        userReactionEventId = reactionEvent.id;
      }
    }

    // Only log in debug mode to reduce console noise
    if (import.meta.env.DEV && false) { // Disable verbose logging
      console.debug(`[FeedReactionButtons] Processed reactions summary:`, {
        totalReactions: reactionEvents.length,
        skippedInvalid,
        reactionCounts: Array.from(reactionMap.entries()).map(([content, data]) => ({
          content,
          count: data.pubkeys.size
        }))
      });
    }

    reactions = reactionMap;
    
    // Resolve custom emojis - include event author's pubkey as they may have defined emojis
    // First resolve with original function (reactors' emojis), then enhance with event author
    const emojiUrls = await resolveCustomEmojis(reactionMap);
    
    // Collect all pubkeys to check: event author, reactors, and p tags from the event
    const pubkeysToCheck = new Set<string>();
    pubkeysToCheck.add(event.pubkey); // Event author
    for (const { pubkeys } of reactionMap.values()) {
      for (const pubkey of pubkeys) {
        pubkeysToCheck.add(pubkey);
      }
    }
    // Also check p tags from the event (mentioned users might have emoji sets)
    for (const tag of event.tags) {
      if (tag[0] === 'p' && tag[1]) {
        pubkeysToCheck.add(tag[1]);
      }
    }
    
    // Check all collected pubkeys for unresolved text emojis
    const unresolvedTextEmojis = Array.from(reactionMap.keys()).filter(
      c => c.startsWith(':') && c.endsWith(':') && !emojiUrls.has(c)
    );
    
    if (unresolvedTextEmojis.length > 0) {
      // Fetch emoji sets for all pubkeys in parallel
      const emojiSetPromises = Array.from(pubkeysToCheck).map(pubkey => 
        fetchEmojiSet(pubkey).catch(() => null)
      );
      const emojiSets = await Promise.all(emojiSetPromises);
      
      // Try to resolve each unresolved emoji
      for (const content of unresolvedTextEmojis) {
        if (emojiUrls.has(content)) continue; // Already resolved
        
        const shortcode = content.slice(1, -1); // Remove colons
        
        // First check each emoji set from collected pubkeys
        let found = false;
        for (const emojiSet of emojiSets) {
          if (emojiSet?.emojis.has(shortcode)) {
            const emojiDef = emojiSet.emojis.get(shortcode)!;
            emojiUrls.set(content, emojiDef.url);
            found = true;
            break; // Found it, move to next emoji
          }
        }
        
        // Don't search broadly here - it triggers background fetching
        // Broad search should only happen when emoji picker is opened
      }
    }
    
    // Update state - create new Map to ensure reactivity
    customEmojiUrls = new Map(emojiUrls);
  }

  async function toggleReaction(content: string) {
    if (!sessionManager.isLoggedIn()) {
      alert('Please log in to react');
      return;
    }

    // If clicking the same reaction, delete it
    if (userReaction === content) {
      // Remove reaction by publishing a kind 5 deletion event
      if (userReactionEventId) {
        try {
          const deletionEvent: Omit<NostrEvent, 'id' | 'sig'> = {
            kind: KIND.EVENT_DELETION,
            pubkey: sessionManager.getCurrentPubkey()!,
            created_at: Math.floor(Date.now() / 1000),
            tags: [['e', userReactionEventId]],
            content: ''
          };

          const relays = relayManager.getReactionPublishRelays();
          const results = await signAndPublish(deletionEvent, relays);
          publicationResults = results;
          publicationModalOpen = true;
          
          // Update local state
          userReaction = null;
          userReactionEventId = null;
          const reaction = reactions.get(content);
          if (reaction) {
            const currentUser = sessionManager.getCurrentPubkey();
            if (currentUser) {
              reaction.pubkeys.delete(currentUser);
              reaction.eventIds.delete(currentUser);
              if (reaction.pubkeys.size === 0) {
                reactions.delete(content);
              }
            }
          }
        } catch (error) {
          console.error('Error deleting reaction:', error);
          alert('Error deleting reaction');
        }
      } else {
        // Fallback: just update UI if we don't have the event ID
        userReaction = null;
        userReactionEventId = null;
        const reaction = reactions.get(content);
        if (reaction) {
          const currentUser = sessionManager.getCurrentPubkey();
          if (currentUser) {
            reaction.pubkeys.delete(currentUser);
            reaction.eventIds.delete(currentUser);
            if (reaction.pubkeys.size === 0) {
              reactions.delete(content);
            }
          }
        }
      }
      return;
    }

    try {
      const tags: string[][] = [
        ['e', event.id],
        ['p', event.pubkey],
        ['k', event.kind.toString()]
      ];

      if (sessionManager.getCurrentPubkey() && shouldIncludeClientTag()) {
        tags.push(['client', 'aitherboard']);
      }

      const reactionEvent: Omit<NostrEvent, 'id' | 'sig'> = {
        kind: KIND.REACTION,
        pubkey: sessionManager.getCurrentPubkey()!,
        created_at: Math.floor(Date.now() / 1000),
        tags,
        content
      };

      // Sign the event first to get the ID
      const signedEvent = await sessionManager.signEvent(reactionEvent);
      
      // Publish the signed event using reaction publish relays (filters read-only relays)
      const relays = relayManager.getReactionPublishRelays();
      const results = await nostrClient.publish(signedEvent, { relays });
      publicationResults = results;
      publicationModalOpen = true;

      // Update local state with the new reaction
      userReaction = content;
      userReactionEventId = signedEvent.id;
      const currentPubkey = sessionManager.getCurrentPubkey()!;
      if (!reactions.has(content)) {
        reactions.set(content, { content, pubkeys: new Set([currentPubkey]), eventIds: new Map([[currentPubkey, signedEvent.id]]) });
      } else {
        reactions.get(content)!.pubkeys.add(currentPubkey);
        reactions.get(content)!.eventIds.set(currentPubkey, signedEvent.id);
      }
    } catch (error) {
      console.error('Error publishing reaction:', error);
    }
  }

  function getReactionDisplay(content: string): string {
    // For +, we'll render it as heart icon in the template
    if (content.startsWith(':') && content.endsWith(':')) {
      const url = customEmojiUrls.get(content);
      if (url) {
        return content; // Custom emoji with URL - will be rendered as image
      }
      // Text emoji without URL - return the shortcode for display
      return content;
    }
    return content;
  }
  
  function formatTextEmoji(content: string): string {
    // Format text emojis like ":clap:" to "Clap" for display (fallback when no image URL)
    if (content.startsWith(':') && content.endsWith(':')) {
      const shortcode = content.slice(1, -1); // Remove colons
      // Capitalize first letter
      return shortcode.charAt(0).toUpperCase() + shortcode.slice(1);
    }
    return content;
  }
  
  // Make this reactive so it updates when customEmojiUrls changes
  function hasEmojiUrl(content: string): boolean {
    // Check if this text emoji has a resolved URL
    // Access customEmojiUrls to make this reactive
    const urls = customEmojiUrls;
    if (content.startsWith(':') && content.endsWith(':')) {
      return urls.has(content);
    }
    return false;
  }
  
  function isCustomEmoji(content: string): boolean {
    return content.startsWith(':') && content.endsWith(':') && customEmojiUrls.has(content);
  }
  
  function getCustomEmojiUrl(content: string): string | null {
    return customEmojiUrls.get(content) || null;
  }

  function getReactionCount(content: string): number {
    return reactions.get(content)?.pubkeys.size || 0;
  }

  function getAllReactions(): Array<{ content: string; count: number }> {
    const allReactions: Array<{ content: string; count: number }> = [];
    for (const [content, data] of reactions.entries()) {
      if (data.pubkeys.size > 0) {
        allReactions.push({ content, count: data.pubkeys.size });
      }
    }
    return allReactions.sort((a, b) => {
      if (b.count !== a.count) return b.count - a.count;
      return a.content.localeCompare(b.content);
    });
  }

  function getCustomEmojis(): string[] {
    const customEmojis: string[] = [];
    const allUnicodeEmojis = new Set<string>();
    // Build set of all Unicode emojis
    for (let i = 0; i < emojiData.length; i++) {
      const emoji = emojiData[i];
      if (typeof emoji === 'string' && emoji.trim()) {
        allUnicodeEmojis.add(emoji);
      }
    }
    // Get custom emojis from reactions (those that aren't Unicode emojis)
    for (const content of reactions.keys()) {
      if (content.startsWith(':') && content.endsWith(':') && !allUnicodeEmojis.has(content)) {
        customEmojis.push(content);
      }
    }
    return customEmojis.sort();
  }
  
  function closeMenuOnOutsideClick(e: MouseEvent) {
    const target = e.target as HTMLElement;
    if (menuButton && 
        !menuButton.contains(target) && 
        !target.closest('.emoji-drawer')) {
      showMenu = false;
    }
  }

  function handleHeartClick(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();
    
    if (showMenu) {
      showMenu = false;
    } else {
      showMenu = true;
    }
  }

  $effect(() => {
    if (showMenu) {
      // Prevent body scroll when drawer is open
      document.body.style.overflow = 'hidden';
      
      
      const timeoutId = setTimeout(() => {
        document.addEventListener('click', closeMenuOnOutsideClick, true);
      }, 0);
      
      return () => {
        clearTimeout(timeoutId);
        document.removeEventListener('click', closeMenuOnOutsideClick, true);
        document.body.style.overflow = '';
      };
    }
  });

  const isLoggedIn = $derived(sessionManager.isLoggedIn());
</script>

<div class="Feed-reaction-buttons flex gap-2 items-center flex-wrap">
  <!-- Full reaction menu for feed posts -->
  {#if isLoggedIn}
    <div class="reaction-wrapper">
      <button
        bind:this={menuButton}
        onclick={handleHeartClick}
        class="reaction-btn heart-btn {userReaction === '+' ? 'active' : ''}"
        title="Like or choose reaction"
        aria-label="Like or choose reaction"
      >
        <Icon name="heart" size={16} />
      </button>
    
      <EmojiPicker
        open={showMenu}
        onSelect={(emoji) => {
          toggleReaction(emoji);
          showMenu = false;
        }}
        onClose={() => { showMenu = false; }}
      />
    </div>
  {/if}

  {#each getAllReactions() as { content, count }}
    {@const reactionData = reactions.get(content)}
    {@const pubkeys = reactionData ? Array.from(reactionData.pubkeys) : []}
    <span
      class="reaction-display {userReaction === content ? 'active' : ''}"
      title={content === '+' ? 'Liked' : `Reacted with ${content}`}
      role="presentation"
      onmouseenter={(e) => {
        hoveredReaction = content;
        hoveredReactionElement = e.currentTarget;
        // Calculate tooltip position
        const rect = e.currentTarget.getBoundingClientRect();
        const tooltipWidth = 300; // max-width from CSS
        const tooltipHeight = 200; // max-height from CSS
        let left = rect.left;
        let top = rect.bottom + 5;
        
        // Adjust if tooltip would go off right edge
        if (left + tooltipWidth > window.innerWidth) {
          left = window.innerWidth - tooltipWidth - 10;
        }
        
        // Adjust if tooltip would go off left edge
        if (left < 10) {
          left = 10;
        }
        
        // Adjust if tooltip would go off bottom edge (show above instead)
        if (top + tooltipHeight > window.innerHeight) {
          top = rect.top - tooltipHeight - 5;
        }
        
        // Adjust if tooltip would go off top edge
        if (top < 10) {
          top = 10;
        }
        
        tooltipPosition = { top, left };
      }}
      onmouseleave={() => {
        hoveredReaction = null;
        hoveredReactionElement = null;
        tooltipPosition = null;
      }}
    >
      {#if content === '+'}
        <Icon name="heart" size={16} />
      {:else if content.startsWith(':') && content.endsWith(':')}
        <!-- Text emoji - try to display as image if URL available -->
        {#if hasEmojiUrl(content)}
          {@const url = getCustomEmojiUrl(content)}
          {#if url}
            <img src={url} alt={content} class="custom-emoji-img" />
          {:else}
            <span class="text-emoji">{formatTextEmoji(content)}</span>
          {/if}
        {:else}
          <span class="text-emoji">{formatTextEmoji(content)}</span>
        {/if}
      {:else}
        {content}
      {/if}
      <span class="reaction-count-text">{count}</span>
    </span>
    
    {#if hoveredReaction === content && tooltipPosition && pubkeys.length > 0}
      <div
        class="reaction-tooltip"
        style="top: {tooltipPosition.top}px; left: {tooltipPosition.left}px;"
        role="tooltip"
        onmouseenter={() => {
          // Keep tooltip visible when hovering over it
        }}
        onmouseleave={() => {
          hoveredReaction = null;
          hoveredReactionElement = null;
          tooltipPosition = null;
        }}
      >
        <div class="reaction-tooltip-content">
          {#each pubkeys as pubkey}
            <div class="reaction-tooltip-badge">
              <ProfileBadge {pubkey} inline={true} />
            </div>
          {/each}
        </div>
      </div>
    {/if}
  {/each}
</div>

<PublicationStatusModal bind:open={publicationModalOpen} bind:results={publicationResults} />

<style>
  .Feed-reaction-buttons {
    margin-top: 0.5rem;
  }
  
  .reaction-btn {
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.25rem;
    background: var(--fog-post, #ffffff);
    color: var(--fog-text, #1f2937);
    cursor: pointer;
    transition: all 0.2s;
    font-size: 0.875rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

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

  .reaction-btn:hover {
    background: var(--fog-highlight, #f3f4f6);
    border-color: var(--fog-accent, #64748b);
  }

  :global(.dark) .reaction-btn:hover {
    background: var(--fog-dark-highlight, #374151);
  }

  .reaction-btn.active {
    background: var(--fog-accent, #64748b);
    color: var(--fog-text, #475569);
    border-color: var(--fog-accent, #64748b);
  }

  :global(.dark) .reaction-btn.active {
    background: var(--fog-dark-accent, #64748b);
    color: var(--fog-dark-text, #cbd5e1);
    border-color: var(--fog-dark-accent, #64748b);
  }

  .reaction-wrapper {
    position: relative;
  }


  .custom-emoji-img {
    width: 1.25rem;
    height: 1.25rem;
    object-fit: contain;
    display: inline-block;
    vertical-align: middle;
  }

  .reaction-display {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    color: var(--fog-text, #1f2937);
    user-select: none;
  }
  
  .reaction-display :global(.icon) {
    flex-shrink: 0;
  }
  
  :global(.dark) .reaction-display {
    color: var(--fog-dark-text, #f9fafb);
  }
  
  .reaction-display.active {
    opacity: 0.8;
  }
  
  .reaction-count-text {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--fog-text-light, #52667a);
  }
  
  :global(.dark) .reaction-count-text {
    color: var(--fog-dark-text-light, #a8b8d0);
  }

  .text-emoji {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--fog-text, #1f2937);
    text-transform: capitalize;
  }
  
  :global(.dark) .text-emoji {
    color: var(--fog-dark-text, #f9fafb);
  }

  .reaction-display {
    position: relative;
  }

  .reaction-tooltip {
    position: fixed;
    z-index: 1000;
    pointer-events: auto;
    max-width: 300px;
  }

  .reaction-tooltip-content {
    background: var(--fog-surface, #ffffff);
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.5rem;
    padding: 0.5rem;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    max-height: 200px;
    overflow-y: auto;
  }

  :global(.dark) .reaction-tooltip-content {
    background: var(--fog-dark-surface, #1f2937);
    border-color: var(--fog-dark-border, #374151);
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
  }

  .reaction-tooltip-badge {
    display: flex;
    align-items: center;
  }

</style>
