<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 { 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';

  interface Props {
    event: NostrEvent;
    forceUpvoteDownvote?: boolean; // Force upvote/downvote mode (for kind 1111 replies to kind 11 threads)
    preloadedReactions?: NostrEvent[]; // Optional pre-loaded reactions to avoid duplicate fetches
  }

  let { event, forceUpvoteDownvote = false, 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);

  onMount(() => {
    nostrClient.initialize().then(async () => {
      if (event.id) {
        // Use pre-loaded reactions if available, otherwise fetch
        if (preloadedReactions && preloadedReactions.length > 0) {
          for (const r of preloadedReactions) {
            allReactionsMap.set(r.id, r);
          }
          const filtered = await filterDeletedReactions(preloadedReactions);
          processReactions(filtered);
        } else {
          loadReactions();
        }
      }
    });
  });

  // Reload reactions when event changes (but prevent duplicate loads)
  $effect(() => {
    if (event.id && event.id !== lastEventId && !loadingReactions) {
      lastEventId = event.id;
      // Clear previous reactions map when event changes
      allReactionsMap.clear();
      
      // Use pre-loaded reactions if available, otherwise fetch
      if (preloadedReactions && preloadedReactions.length > 0) {
        for (const r of preloadedReactions) {
          allReactionsMap.set(r.id, r);
        }
        filterDeletedReactions(preloadedReactions).then(filtered => {
          processReactions(filtered);
        });
      } else {
        loadReactions();
      }
    }
  });

  // Handle real-time updates - process reactions when new ones arrive
  async function handleReactionUpdate(updated: NostrEvent[]) {
    console.debug(`[FeedReactionButtons] Received reaction update for event ${event.id.substring(0, 16)}...:`, {
      count: updated.length,
      events: updated.map(r => ({
        id: r.id.substring(0, 16) + '...',
        pubkey: r.pubkey.substring(0, 16) + '...',
        content: r.content,
        fullEvent: r
      }))
    });
    
    // Add new reactions to the map
    for (const r of updated) {
      allReactionsMap.set(r.id, r);
    }
    
    // Process all accumulated reactions
    const allReactions = Array.from(allReactionsMap.values());
    const filtered = await filterDeletedReactions(allReactions);
    processReactions(filtered);
  }

  async function loadReactions() {
    // 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 ThreadList behavior
      const reactionRelays = relayManager.getProfileReadRelays();
      console.debug(`[FeedReactionButtons] Loading reactions for event ${event.id.substring(0, 16)}... (kind ${event.kind})`);
      console.debug(`[FeedReactionButtons] Using relays:`, reactionRelays);
      
      // Clear and rebuild reactions map for this event
      allReactionsMap.clear();
      
      const reactionsWithLowerE = await nostrClient.fetchEvents(
        [{ kinds: [KIND.REACTION], '#e': [event.id] }],
        reactionRelays,
        { useCache: true, cacheResults: true, onUpdate: handleReactionUpdate }
      );
      const reactionsWithUpperE = await nostrClient.fetchEvents(
        [{ kinds: [KIND.REACTION], '#E': [event.id] }],
        reactionRelays,
        { useCache: true, cacheResults: true, onUpdate: handleReactionUpdate }
      );
      
      console.debug(`[FeedReactionButtons] Reactions fetched:`, {
        eventId: event.id.substring(0, 16) + '...',
        kind: event.kind,
        withLowerE: reactionsWithLowerE.length,
        withUpperE: reactionsWithUpperE.length,
        lowerE_events: reactionsWithLowerE.map(r => ({
          id: r.id.substring(0, 16) + '...',
          pubkey: r.pubkey.substring(0, 16) + '...',
          content: r.content,
          tags: r.tags.filter(t => t[0] === 'e' || t[0] === 'E'),
          fullEvent: r
        })),
        upperE_events: reactionsWithUpperE.map(r => ({
          id: r.id.substring(0, 16) + '...',
          pubkey: r.pubkey.substring(0, 16) + '...',
          content: r.content,
          tags: r.tags.filter(t => t[0] === 'e' || t[0] === 'E'),
          fullEvent: r
        }))
      });
      
      // 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());
      
      console.debug(`[FeedReactionButtons] All reactions (deduplicated):`, {
        total: reactionEvents.length,
        events: reactionEvents.map(r => ({
          id: r.id.substring(0, 16) + '...',
          pubkey: r.pubkey.substring(0, 16) + '...',
          content: r.content,
          tags: r.tags.filter(t => t[0] === 'e' || t[0] === 'E'),
          created_at: new Date(r.created_at * 1000).toISOString(),
          fullEvent: r
        }))
      });
      
      // Filter out deleted reactions (kind 5)
      const filteredReactions = await filterDeletedReactions(reactionEvents);
      console.debug(`[FeedReactionButtons] After filtering deleted reactions:`, {
        before: reactionEvents.length,
        after: filteredReactions.length,
        filtered: reactionEvents.length - filteredReactions.length,
        events: filteredReactions.map(r => ({
          id: r.id.substring(0, 16) + '...',
          pubkey: r.pubkey.substring(0, 16) + '...',
          content: r.content,
          fullEvent: r
        }))
      });
      
      processReactions(filteredReactions);
    } catch (error) {
      console.error('[FeedReactionButtons] Error loading reactions:', error);
    } finally {
      loading = false;
      loadingReactions = false;
    }
  }

  async function filterDeletedReactions(reactions: NostrEvent[]): Promise<NostrEvent[]> {
    if (reactions.length === 0) return reactions;
    
    // Fetch deletion events (kind 5) to filter out deleted reactions
    const reactionRelays = relayManager.getProfileReadRelays();
    const deletionEvents = await nostrClient.fetchEvents(
      [{ kinds: [KIND.EVENT_DELETION], authors: Array.from(new Set(reactions.map(r => r.pubkey))) }],
      reactionRelays,
      { useCache: true }
    );
    
    console.debug(`[FeedReactionButtons] Deletion events fetched:`, {
      count: deletionEvents.length,
      events: deletionEvents.map(d => ({
        id: d.id.substring(0, 16) + '...',
        pubkey: d.pubkey.substring(0, 16) + '...',
        deletedEventIds: d.tags.filter(t => t[0] === 'e').map(t => t[1]?.substring(0, 16) + '...'),
        fullEvent: d
      }))
    });
    
    // Build a set of deleted reaction event IDs (keyed by pubkey)
    const deletedReactionIdsByPubkey = new Map<string, Set<string>>();
    for (const deletionEvent of deletionEvents) {
      const pubkey = deletionEvent.pubkey;
      if (!deletedReactionIdsByPubkey.has(pubkey)) {
        deletedReactionIdsByPubkey.set(pubkey, new Set());
      }
      // Kind 5 events have 'e' tags pointing to deleted events
      for (const tag of deletionEvent.tags) {
        if (tag[0] === 'e' && tag[1]) {
          deletedReactionIdsByPubkey.get(pubkey)!.add(tag[1]);
        }
      }
    }
    
    console.debug(`[FeedReactionButtons] Deleted reaction IDs by pubkey:`, 
      Array.from(deletedReactionIdsByPubkey.entries()).map(([pubkey, ids]) => ({
        pubkey: pubkey.substring(0, 16) + '...',
        deletedIds: Array.from(ids).map(id => id.substring(0, 16) + '...')
      }))
    );
    
    // Filter out deleted reactions
    const filtered = reactions.filter(reaction => {
      const deletedIds = deletedReactionIdsByPubkey.get(reaction.pubkey);
      const isDeleted = deletedIds && deletedIds.has(reaction.id);
      if (isDeleted) {
        console.debug(`[FeedReactionButtons] Filtering out deleted reaction:`, {
          id: reaction.id.substring(0, 16) + '...',
          pubkey: reaction.pubkey.substring(0, 16) + '...',
          content: reaction.content,
          fullEvent: reaction
        });
      }
      return !isDeleted;
    });
    
    return filtered;
  }

  async function processReactions(reactionEvents: NostrEvent[]) {
    console.debug(`[FeedReactionButtons] Processing ${reactionEvents.length} reactions for event ${event.id.substring(0, 16)}... (kind ${event.kind})`);
    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;
      
      // For kind 11 events (or kind 1111 replies to kind 11), normalize reactions: only + and - allowed
      // Backward compatibility: ⬆️/↑ = +, ⬇️/↓ = -
      if (event.kind === KIND.DISCUSSION_THREAD || forceUpvoteDownvote) {
        if (content === '⬆️' || content === '↑') {
          content = '+';
        } else if (content === '⬇️' || content === '↓') {
          content = '-';
        } else if (content !== '+' && content !== '-') {
          skippedInvalid++;
          console.log(`[FeedReactionButtons] Skipping invalid reaction for kind 11:`, {
            originalContent,
            reactionId: reactionEvent.id.substring(0, 16) + '...',
            pubkey: reactionEvent.pubkey.substring(0, 16) + '...',
            fullEvent: reactionEvent
          });
          continue; // Skip invalid reactions for threads
        }
      }
      
      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;
      }
    }

    console.debug(`[FeedReactionButtons] Processed reactions summary:`, {
      totalReactions: reactionEvents.length,
      skippedInvalid,
      reactionCounts: Array.from(reactionMap.entries()).map(([content, data]) => ({
        content,
        count: data.pubkeys.size,
        pubkeys: Array.from(data.pubkeys).map(p => p.substring(0, 16) + '...'),
        eventIds: Array.from(data.eventIds.entries()).map(([pubkey, eventId]) => ({
          pubkey: pubkey.substring(0, 16) + '...',
          eventId: eventId.substring(0, 16) + '...'
        }))
      })),
      userReaction,
      allReactionEvents: reactionEvents.map(r => ({
        id: r.id.substring(0, 16) + '...',
        pubkey: r.pubkey.substring(0, 16) + '...',
        content: r.content,
        fullEvent: r
      }))
    });

    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
          }
        }
        
        // If not found in specific pubkeys, search broadly
        if (!found) {
          const url = await resolveEmojiShortcode(shortcode, [], true);
          if (url) {
            emojiUrls.set(content, url);
          }
        }
      }
    }
    
    // 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;
    }

    // For kind 11 events (or kind 1111 replies to kind 11), only allow + and - (upvote/downvote)
    if ((event.kind === KIND.DISCUSSION_THREAD || forceUpvoteDownvote) && content !== '+' && content !== '-') {
      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 config = nostrClient.getConfig();
          await signAndPublish(deletionEvent, [...config.defaultRelays]);
          
          // 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;
    }

    // For kind 11 (or kind 1111 replies to kind 11): if user has the opposite vote, delete it first
    if ((event.kind === KIND.DISCUSSION_THREAD || forceUpvoteDownvote) && userReaction && userReaction !== content) {
      // Delete the existing vote first
      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 config = nostrClient.getConfig();
          await signAndPublish(deletionEvent, [...config.defaultRelays]);
          
          // Update local state for the old reaction
          const oldReaction = reactions.get(userReaction);
          if (oldReaction) {
            const currentUser = sessionManager.getCurrentPubkey();
            if (currentUser) {
              oldReaction.pubkeys.delete(currentUser);
              oldReaction.eventIds.delete(currentUser);
              if (oldReaction.pubkeys.size === 0) {
                reactions.delete(userReaction);
              }
            }
          }
        } catch (error) {
          console.error('Error deleting old reaction:', error);
        }
      }
      // Clear the old reaction state
      userReaction = null;
      userReactionEventId = null;
    }

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

      if (sessionManager.getCurrentPubkey() && includeClientTag) {
        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
      };

      const config = nostrClient.getConfig();
      
      // Sign the event first to get the ID
      const signedEvent = await sessionManager.signEvent(reactionEvent);
      
      // Publish the signed event
      await nostrClient.publish(signedEvent, { relays: [...config.defaultRelays] });

      // 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 {
    if (content === '+') return '❤️';
    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 = '';
      };
    }
  });

  let includeClientTag = $state(true);
</script>

<div class="Feed-reaction-buttons flex gap-2 items-center flex-wrap">
  {#if event.kind === KIND.DISCUSSION_THREAD || forceUpvoteDownvote}
    <!-- Kind 11 (Thread) or Kind 1111 (Reply to Thread): Only upvote and downvote buttons -->
    <button
      onclick={() => toggleReaction('+')}
      class="reaction-btn vote-btn {userReaction === '+' ? 'active' : ''}"
      title="Upvote"
      aria-label="Upvote"
    >
      ⬆️ <span class="vote-count {getReactionCount('+') > 0 ? 'has-votes' : ''}">{getReactionCount('+')}</span>
    </button>
    <button
      onclick={() => toggleReaction('-')}
      class="reaction-btn vote-btn {userReaction === '-' ? 'active' : ''}"
      title="Downvote"
      aria-label="Downvote"
    >
      ⬇️ <span class="vote-count {getReactionCount('-') > 0 ? 'has-votes' : ''}">{getReactionCount('-')}</span>
    </button>
  {:else}
    <!-- Kind 1 (Feed): Full reaction menu -->
    <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"
      >
        ❤️
      </button>
    
    <EmojiPicker
      open={showMenu}
      onSelect={(emoji) => {
        toggleReaction(emoji);
        showMenu = false;
      }}
      onClose={() => { showMenu = false; }}
    />
    </div>

    {#if event.kind !== KIND.DISCUSSION_THREAD}
      {#each getAllReactions() as { content, count }}
        <span
          class="reaction-display {userReaction === content ? 'active' : ''}"
          title={content === '+' ? 'Liked' : `Reacted with ${content}`}
        >
          {#if content === '+'}
            ❤️
          {: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>
      {/each}
    {/if}
  {/if}
</div>

<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;
  }

  :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;
  }
  
  :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, #6b7280);
  }
  
  :global(.dark) .reaction-count-text {
    color: var(--fog-dark-text-light, #9ca3af);
  }

  .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);
  }

  .vote-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
  }

  .vote-count {
    transition: color 0.2s;
    color: #9ca3af !important; /* gray-400 for zeros */
  }

  .vote-count.has-votes {
    color: #3b82f6 !important; /* blue-500 - brighter blue like checkbox */
    font-weight: 600; /* semi-bold */
  }

  :global(.dark) .vote-count {
    color: #6b7280 !important; /* gray-500 for zeros in dark mode */
  }

  :global(.dark) .vote-count.has-votes {
    color: #60a5fa !important; /* blue-400 for dark mode - brighter than before */
    font-weight: 600; /* semi-bold */
  }

</style>
