<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 { onMount } from 'svelte';
  import type { NostrEvent } from '../../types/nostr.js';
  import emojiData from 'unicode-emoji-json/data-ordered-emoji.json';
  import { resolveCustomEmojis } from '../../services/nostr/nip30-emoji.js';

  interface Props {
    event: NostrEvent; // Feed event
  }

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

  let reactions = $state<Map<string, { content: string; pubkeys: Set<string> }>>(new Map());
  let userReaction = $state<string | null>(null);
  let loading = $state(true);
  let showMenu = $state(false);
  let menuButton: HTMLButtonElement | null = $state(null);
  let menuPosition = $state<'above' | 'below'>('above'); // Track menu position
  let customEmojiUrls = $state<Map<string, string>>(new Map()); // Map of :shortcode: -> image URL
  let emojiSearchQuery = $state('');
  let isMobile = $state(false);
  
  // Derived value for heart count
  let heartCount = $derived(getReactionCount('+'));

  // Get emoji list from unicode-emoji-json library
  // The library provides an array of emoji strings in order
  const reactionMenu = $derived.by(() => {
    const emojis: string[] = ['+']; // Heart (default) always first
    
    // Add ALL emojis from the library - the menu will scroll
    // The data-ordered-emoji.json is already an array of emoji strings
    for (let i = 0; i < emojiData.length; i++) {
      const emoji = emojiData[i];
      if (typeof emoji === 'string' && emoji.trim()) {
        emojis.push(emoji);
      }
    }
    
    return emojis;
  });
  
  // Filter emojis based on search query
  const filteredReactionMenu = $derived.by(() => {
    if (!emojiSearchQuery.trim()) {
      return reactionMenu;
    }
    
    const query = emojiSearchQuery.toLowerCase().trim();
    return reactionMenu.filter(emoji => {
      // Search by emoji character itself
      if (emoji.toLowerCase().includes(query)) {
        return true;
      }
      // For custom emojis, search by shortcode
      if (emoji.startsWith(':') && emoji.endsWith(':')) {
        return emoji.toLowerCase().includes(query);
      }
      // Try to match emoji unicode name (basic approach)
      // This is a simple search - could be enhanced with proper emoji name data
      return false;
    });
  });

  // Custom emoji reactions (like :turtlehappy_sm:)
  // These will be added dynamically from actual reactions received

  onMount(() => {
    nostrClient.initialize().then(() => {
      loadReactions();
    });
    
    // Check if mobile on mount and resize
    checkMobile();
    window.addEventListener('resize', checkMobile);
    
    return () => {
      window.removeEventListener('resize', checkMobile);
    };
  });
  
  function checkMobile() {
    isMobile = window.innerWidth < 768; // Match Tailwind's md breakpoint
  }

  async function loadReactions() {
    loading = true;
    try {
      const config = nostrClient.getConfig();
      
      const filters = [
        {
          kinds: [7],
          '#e': [event.id]
        }
      ];

      const reactionEvents = await nostrClient.fetchEvents(
        filters,
        [...config.defaultRelays],
        { useCache: true, cacheResults: true, onUpdate: (updated) => {
          processReactions(updated);
        }}
      );

      processReactions(reactionEvents);
    } catch (error) {
      console.error('Error loading reactions:', error);
    } finally {
      loading = false;
    }
  }

  async function processReactions(reactionEvents: NostrEvent[]) {
    const reactionMap = new Map<string, { content: string; pubkeys: Set<string> }>();
    const currentUser = sessionManager.getCurrentPubkey();

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

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

    reactions = reactionMap;
    
    // Resolve custom emojis (NIP-30) to image URLs
    const emojiUrls = await resolveCustomEmojis(reactionMap);
    customEmojiUrls = emojiUrls;
  }

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

    if (userReaction === content) {
      // Remove reaction
      userReaction = null;
      const reaction = reactions.get(content);
      if (reaction) {
        const currentUser = sessionManager.getCurrentPubkey();
        if (currentUser) {
          reaction.pubkeys.delete(currentUser);
          if (reaction.pubkeys.size === 0) {
            reactions.delete(content);
          }
        }
      }
      return;
    }

    try {
      const tags: string[][] = [
        ['e', event.id],
        ['p', event.pubkey],
        ['k', '1']
      ];

      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();
      await signAndPublish(reactionEvent, [...config.defaultRelays]);

      userReaction = content;
      const currentPubkey = sessionManager.getCurrentPubkey()!;
      if (!reactions.has(content)) {
        reactions.set(content, { content, pubkeys: new Set([currentPubkey]) });
      } else {
        reactions.get(content)!.pubkeys.add(currentPubkey);
      }
    } catch (error) {
      console.error('Error publishing reaction:', error);
      alert('Error publishing reaction');
    }
  }

  function getReactionDisplay(content: string): string {
    if (content === '+') return '❤️';
    
    // Check if this is a custom emoji with a resolved URL
    if (content.startsWith(':') && content.endsWith(':')) {
      const url = customEmojiUrls.get(content);
      if (url) {
        // Return a placeholder that will be replaced with img tag in template
        return content; // We'll render as img in template
      }
    }
    
    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 }> {
    // Get all reactions that have counts > 0, sorted by count (descending)
    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 });
      }
    }
    // Sort by count descending, then by content
    return allReactions.sort((a, b) => {
      if (b.count !== a.count) return b.count - a.count;
      return a.content.localeCompare(b.content);
    });
  }

  function getCustomEmojis(): string[] {
    // Extract custom emoji reactions (format: :name:)
    const customEmojis: string[] = [];
    for (const content of reactions.keys()) {
      if (content.startsWith(':') && content.endsWith(':') && !reactionMenu.includes(content)) {
        customEmojis.push(content);
      }
    }
    return customEmojis.sort();
  }
  
  // Filter custom emojis based on search query
  const filteredCustomEmojis = $derived.by(() => {
    const customEmojis = getCustomEmojis();
    if (!emojiSearchQuery.trim()) {
      return customEmojis;
    }
    
    const query = emojiSearchQuery.toLowerCase().trim();
    return customEmojis.filter(emoji => {
      // Search by shortcode (e.g., :turtlehappy_sm:)
      return 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 = ''; // Clear search when closing
    }
  }

  function handleHeartClick() {
    if (showMenu) {
      // If menu is open, clicking heart again should just like/unlike
      toggleReaction('+');
      showMenu = false;
      emojiSearchQuery = ''; // Clear search when closing
    } else {
      // On mobile, always use bottom drawer
      if (isMobile) {
        menuPosition = 'below';
      } else {
        // Check if there's enough space above the button
        if (menuButton) {
          const rect = menuButton.getBoundingClientRect();
          const spaceAbove = rect.top;
          const spaceBelow = window.innerHeight - rect.bottom;
          // Position below if there's more space below or if space above is less than 300px
          menuPosition = spaceBelow > spaceAbove || spaceAbove < 300 ? 'below' : 'above';
        }
      }
      // If menu is closed, open it
      showMenu = true;
      emojiSearchQuery = ''; // Clear search when opening
      
      // Focus search input after menu opens (using setTimeout to ensure DOM is ready)
      if (!isMobile) {
        setTimeout(() => {
          const searchInput = document.querySelector('.emoji-search-input') as HTMLInputElement;
          if (searchInput) {
            searchInput.focus();
          }
        }, 0);
      }
    }
  }
  
  function handleSearchInput(e: Event) {
    const target = e.target as HTMLInputElement;
    emojiSearchQuery = target.value;
  }
  
  // Action to focus input when menu opens
  function focusOnMount(node: HTMLInputElement, shouldFocus: boolean) {
    if (shouldFocus) {
      setTimeout(() => node.focus(), 0);
    }
    return {
      update(newShouldFocus: boolean) {
        if (newShouldFocus) {
          setTimeout(() => node.focus(), 0);
        }
      }
    };
  }

  $effect(() => {
    if (showMenu) {
      document.addEventListener('click', closeMenuOnOutsideClick);
      return () => document.removeEventListener('click', closeMenuOnOutsideClick);
    }
  });

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

<div class="Feed-reaction-buttons flex gap-2 items-center flex-wrap">
  <!-- Heart button - always visible, opens 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"
    >
      ❤️ {heartCount > 0 ? heartCount : ''}
    </button>
    
    <!-- Reaction menu dropdown -->
    {#if showMenu}
      {#if isMobile}
        <!-- Mobile backdrop -->
        <div 
          class="mobile-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>
      {/if}
      <div class="reaction-menu" class:menu-below={menuPosition === 'below'} class:mobile-drawer={isMobile}>
        <!-- Search box - always visible at top -->
        <div class="emoji-search-container">
          <input
            type="text"
            placeholder="Search emojis..."
            value={emojiSearchQuery}
            oninput={handleSearchInput}
            class="emoji-search-input"
            aria-label="Search emojis"
            use:focusOnMount={!isMobile}
          />
        </div>
        
        <!-- Scrollable content area -->
        <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>
        
        <!-- Custom emojis section -->
        {#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>

  <!-- Display all other reactions that have counts > 0 (except + which is shown as heart) -->
  {#each getAllReactions() as { content, count }}
    {#if content !== '+'}
      <button
        onclick={() => toggleReaction(content)}
        class="reaction-btn {userReaction === content ? 'active' : ''}"
        title={`React with ${content}`}
        aria-label={`React with ${content}`}
      >
        {#if isCustomEmoji(content)}
          {@const url = getCustomEmojiUrl(content)}
          {#if url}
            <img src={url} alt={content} class="custom-emoji-img" />
          {:else}
            {content}
          {/if}
        {:else}
          {content}
        {/if}
        {count}
      </button>
    {/if}
  {/each}
</div>

<style>
  .Feed-reaction-buttons {
    margin-top: 0.5rem;
  }
  
  @media (max-width: 768px) {
    .Feed-reaction-buttons {
      gap: 0.375rem; /* Smaller gap on mobile */
    }
    
    .reaction-btn {
      padding: 0.25rem 0.5rem; /* Smaller padding on mobile */
      font-size: 0.8125rem; /* Slightly smaller text */
    }
  }

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

  .heart-btn {
    /* Heart button styling */
  }

  .reaction-menu {
    position: absolute;
    bottom: 100%;
    left: 0;
    margin-bottom: 0.5rem;
    background: var(--fog-post, #ffffff);
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.5rem;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    padding: 0.5rem;
    z-index: 1000;
    min-width: 200px;
    max-width: 300px;
    max-height: min(60vh, 400px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Ensure scrollbar is always visible */
    scrollbar-width: thin;
    scrollbar-color: var(--fog-border, #e5e7eb) var(--fog-post, #ffffff);
  }
  
  .reaction-menu-content {
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1;
  }
  
  /* Mobile drawer styles */
  .reaction-menu.mobile-drawer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    top: auto;
    margin: 0;
    border-radius: 1rem 1rem 0 0;
    max-width: 100%;
    max-height: 70vh;
    min-width: auto;
    width: 100%;
    box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1), 0 -2px 4px -1px rgba(0, 0, 0, 0.06);
    animation: slideUp 0.3s ease-out;
  }
  
  @keyframes slideUp {
    from {
      transform: translateY(100%);
    }
    to {
      transform: translateY(0);
    }
  }
  
  /* Backdrop for mobile drawer */
  .mobile-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.mobile-drawer {
    z-index: 1000;
  }

  .reaction-menu.menu-below {
    bottom: auto;
    top: 100%;
    margin-bottom: 0;
    margin-top: 0.5rem;
  }

  .reaction-menu::-webkit-scrollbar {
    width: 8px;
  }

  .reaction-menu::-webkit-scrollbar-track {
    background: var(--fog-post, #ffffff);
    border-radius: 0.5rem;
  }

  .reaction-menu::-webkit-scrollbar-thumb {
    background: var(--fog-border, #e5e7eb);
    border-radius: 4px;
  }

  .reaction-menu::-webkit-scrollbar-thumb:hover {
    background: var(--fog-accent, #64748b);
  }

  :global(.dark) .reaction-menu::-webkit-scrollbar-track {
    background: var(--fog-dark-post, #1f2937);
  }

  :global(.dark) .reaction-menu::-webkit-scrollbar-thumb {
    background: var(--fog-dark-border, #374151);
  }

  :global(.dark) .reaction-menu::-webkit-scrollbar-thumb:hover {
    background: var(--fog-dark-accent, #64748b);
  }

  :global(.dark) .reaction-menu {
    background: var(--fog-dark-post, #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-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;
  }

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

  .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-bottom: 0.5rem;
    padding-bottom: 0.5rem;
    padding-top: 0;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
    display: block;
    width: 100%;
  }
  
  :global(.dark) .emoji-search-container {
    border-bottom-color: var(--fog-dark-border, #374151);
  }
  
  .emoji-search-input {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.25rem;
    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.1);
  }
  
  :global(.dark) .emoji-search-input {
    background: var(--fog-dark-post, #1f2937);
    border-color: var(--fog-dark-border, #374151);
    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.2);
  }
  
  /* Adjust grid for mobile */
  @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>
