<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 emojiData from 'unicode-emoji-json/data-ordered-emoji.json';
  import emojiNames from 'unicode-emoji-json/data-by-emoji.json';
  import { resolveCustomEmojis } from '../../services/nostr/nip30-emoji.js';

  interface Props {
    event: NostrEvent;
    forceUpvoteDownvote?: boolean; // Force upvote/downvote mode (for kind 1111 replies to kind 11 threads)
  }

  let { event, forceUpvoteDownvote = false }: 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 emojiSearchQuery = $state('');
  let allReactionsMap = $state<Map<string, NostrEvent>>(new Map()); // Persist reactions map for real-time updates
  
  let heartCount = $derived(getReactionCount('+'));

  const reactionMenu = $derived.by(() => {
    const emojis: string[] = ['+'];
    for (let i = 0; i < emojiData.length; i++) {
      const emoji = emojiData[i];
      if (typeof emoji === 'string' && emoji.trim()) {
        emojis.push(emoji);
      }
    }
    return emojis;
  });
  
  const filteredReactionMenu = $derived.by(() => {
    if (!emojiSearchQuery.trim()) {
      return reactionMenu;
    }
    const query = emojiSearchQuery.toLowerCase().trim();
    return reactionMenu.filter(emoji => {
      // For custom emojis (shortcodes), search the shortcode itself
      if (emoji.startsWith(':') && emoji.endsWith(':')) {
        return emoji.toLowerCase().includes(query);
      }
      
      // For regular emojis, search by name
      const emojiInfo = (emojiNames as Record<string, { name?: string; slug?: string }>)[emoji];
      if (emojiInfo) {
        const name = emojiInfo.name?.toLowerCase() || '';
        const slug = emojiInfo.slug?.toLowerCase() || '';
        if (name.includes(query) || slug.includes(query)) {
          return true;
        }
      }
      
      // Fallback: search the emoji character itself (though this rarely matches)
      return emoji.toLowerCase().includes(query);
    });
  });

  onMount(() => {
    nostrClient.initialize().then(() => {
      loadReactions();
    });
  });

  // Reload reactions when event changes
  $effect(() => {
    if (event.id) {
      // Clear previous reactions map when event changes
      allReactionsMap.clear();
      loadReactions();
    }
  });

  // Handle real-time updates - process reactions when new ones arrive
  async function handleReactionUpdate(updated: NostrEvent[]) {
    console.log(`[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() {
    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.log(`[FeedReactionButtons] Loading reactions for event ${event.id.substring(0, 16)}... (kind ${event.kind})`);
      console.log(`[FeedReactionButtons] Using relays:`, reactionRelays);
      
      // Clear and rebuild reactions map for this event
      allReactionsMap.clear();
      
      const reactionsWithLowerE = await nostrClient.fetchEvents(
        [{ kinds: [7], '#e': [event.id] }],
        reactionRelays,
        { useCache: true, cacheResults: true, onUpdate: handleReactionUpdate }
      );
      const reactionsWithUpperE = await nostrClient.fetchEvents(
        [{ kinds: [7], '#E': [event.id] }],
        reactionRelays,
        { useCache: true, cacheResults: true, onUpdate: handleReactionUpdate }
      );
      
      console.log(`[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.log(`[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.log(`[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;
    }
  }

  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: [5], authors: Array.from(new Set(reactions.map(r => r.pubkey))) }],
      reactionRelays,
      { useCache: true }
    );
    
    console.log(`[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.log(`[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.log(`[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.log(`[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 === 11 || 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.log(`[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;
    const emojiUrls = await resolveCustomEmojis(reactionMap);
    customEmojiUrls = 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 === 11 || 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: 5,
            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 === 11 || forceUpvoteDownvote) && userReaction && userReaction !== content) {
      // Delete the existing vote first
      if (userReactionEventId) {
        try {
          const deletionEvent: Omit<NostrEvent, 'id' | 'sig'> = {
            kind: 5,
            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: 7,
        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;
      }
    }
    return content;
  }
  
  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[] = [];
    for (const content of reactions.keys()) {
      if (content.startsWith(':') && content.endsWith(':') && !reactionMenu.includes(content)) {
        customEmojis.push(content);
      }
    }
    return customEmojis.sort();
  }
  
  const filteredCustomEmojis = $derived.by(() => {
    const customEmojis = getCustomEmojis();
    if (!emojiSearchQuery.trim()) {
      return customEmojis;
    }
    const query = emojiSearchQuery.toLowerCase().trim();
    return customEmojis.filter(emoji => emoji.toLowerCase().includes(query));
  });

  function closeMenuOnOutsideClick(e: MouseEvent) {
    const target = e.target as HTMLElement;
    if (menuButton && 
        !menuButton.contains(target) && 
        !target.closest('.reaction-menu')) {
      showMenu = false;
      emojiSearchQuery = '';
    }
  }

  function handleHeartClick(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();
    
    if (showMenu) {
      showMenu = false;
      emojiSearchQuery = '';
    } else {
      showMenu = true;
      emojiSearchQuery = '';
    }
  }
  
  function handleSearchInput(e: Event) {
    const target = e.target as HTMLInputElement;
    emojiSearchQuery = target.value;
  }

  $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 === 11 || 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>
    
    {#if showMenu}
      <div 
        class="drawer-backdrop" 
        onclick={() => { showMenu = false; emojiSearchQuery = ''; }}
        onkeydown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            showMenu = false;
            emojiSearchQuery = '';
          }
        }}
        role="button"
        tabindex="0"
        aria-label="Close emoji menu"
      ></div>
      <div class="reaction-menu drawer-left">
        <div class="drawer-header">
          <h3 class="drawer-title">Choose Reaction</h3>
          <button
            onclick={() => { showMenu = false; emojiSearchQuery = ''; }}
            class="drawer-close"
            aria-label="Close emoji menu"
            title="Close"
          >
            ×
          </button>
        </div>
        <div class="emoji-search-container">
          <input
            type="text"
            placeholder="Search emojis..."
            value={emojiSearchQuery}
            oninput={handleSearchInput}
            class="emoji-search-input"
            aria-label="Search emojis"
          />
        </div>
        
        <div class="reaction-menu-content">
          <div class="reaction-menu-grid">
            {#each filteredReactionMenu as reaction}
              {@const count = getReactionCount(reaction)}
              <button
                onclick={() => {
                  toggleReaction(reaction);
                  showMenu = false;
                }}
                class="reaction-menu-item {userReaction === reaction ? 'active' : ''}"
                title={reaction === '+' ? 'Like' : `React with ${getReactionDisplay(reaction)}`}
              >
                {#if isCustomEmoji(reaction)}
                  {@const url = getCustomEmojiUrl(reaction)}
                  {#if url}
                    <img src={url} alt={reaction} class="custom-emoji-img" />
                  {:else}
                    {reaction}
                  {/if}
                {:else}
                  {getReactionDisplay(reaction)}
                {/if}
                {#if count > 0}
                  <span class="reaction-count">{count}</span>
                {/if}
              </button>
            {/each}
          </div>
          
          {#if filteredCustomEmojis.length > 0}
            <div class="custom-emojis-section">
              <div class="custom-emojis-label">Custom</div>
              <div class="reaction-menu-grid">
                {#each filteredCustomEmojis as emoji}
                  {@const count = getReactionCount(emoji)}
                  <button
                    onclick={() => {
                      toggleReaction(emoji);
                      showMenu = false;
                    }}
                    class="reaction-menu-item {userReaction === emoji ? 'active' : ''}"
                    title={`React with ${emoji}`}
                  >
                    {#if isCustomEmoji(emoji)}
                      {@const url = getCustomEmojiUrl(emoji)}
                      {#if url}
                        <img src={url} alt={emoji} class="custom-emoji-img" />
                      {:else}
                        {emoji}
                      {/if}
                    {:else}
                      {emoji}
                    {/if}
                    {#if count > 0}
                      <span class="reaction-count">{count}</span>
                    {/if}
                  </button>
                {/each}
              </div>
            </div>
          {/if}
        </div>
      </div>
    {/if}
    </div>

    {#if event.kind !== 11}
      {#each getAllReactions() as { content, count }}
        <span
          class="reaction-display {userReaction === content ? 'active' : ''}"
          title={content === '+' ? 'Liked' : `Reacted with ${content}`}
        >
          {#if content === '+'}
            ❤️
          {:else if isCustomEmoji(content)}
            {@const url = getCustomEmojiUrl(content)}
            {#if url}
              <img src={url} alt={content} class="custom-emoji-img" />
            {:else}
              {content}
            {/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;
  }

  .drawer-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
    animation: fadeIn 0.3s ease-out;
  }
  
  @keyframes fadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  .reaction-menu {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(400px, 80vw);
    max-width: 400px;
    background: var(--fog-post, #ffffff);
    border-right: 2px solid var(--fog-border, #cbd5e1);
    box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
    padding: 0;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: slideInLeft 0.3s ease-out;
    transform: translateX(0);
  }
  
  .drawer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
  }
  
  :global(.dark) .drawer-header {
    border-bottom-color: var(--fog-dark-border, #374151);
  }
  
  .drawer-title {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--fog-text, #1f2937);
  }
  
  :global(.dark) .drawer-title {
    color: var(--fog-dark-text, #f9fafb);
  }
  
  .drawer-close {
    background: transparent;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    color: var(--fog-text-light, #9ca3af);
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
    transition: all 0.2s;
  }
  
  .drawer-close:hover {
    background: var(--fog-highlight, #f3f4f6);
    color: var(--fog-text, #1f2937);
  }
  
  :global(.dark) .drawer-close {
    color: var(--fog-dark-text-light, #6b7280);
  }
  
  :global(.dark) .drawer-close:hover {
    background: var(--fog-dark-highlight, #374151);
    color: var(--fog-dark-text, #f9fafb);
  }
  
  @keyframes slideInLeft {
    from {
      transform: translateX(-100%);
    }
    to {
      transform: translateX(0);
    }
  }
  
  .reaction-menu-content {
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1;
    margin-top: 0.5rem;
  }

  :global(.dark) .reaction-menu {
    background: var(--fog-dark-post, #1f2937);
    border-right-color: var(--fog-dark-border, #475569);
    box-shadow: 2px 0 10px rgba(0, 0, 0, 0.5);
  }

  .reaction-menu-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.25rem;
  }

  .reaction-menu-item {
    position: relative;
    padding: 0.5rem;
    border: 1px solid transparent;
    border-radius: 0.25rem;
    background: transparent;
    cursor: pointer;
    transition: all 0.2s;
    font-size: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 2.5rem;
    filter: none !important;
  }
  
  .reaction-menu-item * {
    filter: none !important;
  }

  .reaction-menu-item:hover {
    background: var(--fog-highlight, #f3f4f6);
    border-color: var(--fog-border, #e5e7eb);
  }

  :global(.dark) .reaction-menu-item:hover {
    background: var(--fog-dark-highlight, #374151);
    border-color: var(--fog-dark-border, #374151);
  }

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

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

  .reaction-count {
    position: absolute;
    bottom: 0.125rem;
    right: 0.125rem;
    font-size: 0.625rem;
    font-weight: 600;
    background: var(--fog-accent, #64748b);
    color: white;
    border-radius: 50%;
    width: 1rem;
    height: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
  }

  :global(.dark) .reaction-count {
    background: var(--fog-dark-accent, #64748b);
  }

  .custom-emojis-section {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--fog-border, #e5e7eb);
  }

  :global(.dark) .custom-emojis-section {
    border-top-color: var(--fog-dark-border, #475569);
  }

  .custom-emojis-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--fog-text-light, #6b7280);
    margin-bottom: 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  :global(.dark) .custom-emojis-label {
    color: var(--fog-dark-text-light, #9ca3af);
  }

  .custom-emoji-img {
    width: 1.25rem;
    height: 1.25rem;
    object-fit: contain;
    display: inline-block;
    vertical-align: middle;
  }
  
  .emoji-search-container {
    margin: 0;
    padding: 1rem;
    padding-top: 0.75rem;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
    display: block;
    width: 100%;
  }
  
  :global(.dark) .emoji-search-container {
    border-bottom-color: var(--fog-dark-border, #475569);
  }
  
  .emoji-search-input {
    width: 100%;
    padding: 0.625rem;
    border: 1.5px solid var(--fog-border, #cbd5e1);
    border-radius: 0.375rem;
    background: var(--fog-post, #ffffff);
    color: var(--fog-text, #1f2937);
    font-size: 0.875rem;
    display: block;
    box-sizing: border-box;
  }
  
  .emoji-search-input:focus {
    outline: none;
    border-color: var(--fog-accent, #64748b);
    box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.15);
  }
  
  :global(.dark) .emoji-search-input {
    background: var(--fog-dark-post, #1f2937);
    border-color: var(--fog-dark-border, #475569);
    color: var(--fog-dark-text, #f9fafb);
  }
  
  :global(.dark) .emoji-search-input:focus {
    border-color: var(--fog-dark-accent, #64748b);
    box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.3);
  }

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

  .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 */
  }

  @media (max-width: 768px) {
    .reaction-menu-grid {
      grid-template-columns: repeat(8, 1fr);
    }
    
    .reaction-menu-item {
      min-height: 2.25rem;
      font-size: 1.125rem;
    }
  }
</style>
