<script lang="ts">
  import emojiData from 'unicode-emoji-json/data-ordered-emoji.json';
  import emojiNames from 'unicode-emoji-json/data-by-emoji.json';
  import EmojiDrawer from './EmojiDrawer.svelte';
  import { loadAllEmojiPacks, getAllCustomEmojis } from '../../services/nostr/nip30-emoji.js';
  import { signAndPublish } from '../../services/nostr/auth-handler.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { sessionManager } from '../../services/auth/session-manager.js';
  import { KIND } from '../../types/kind-lookup.js';
  import type { NostrEvent } from '../../types/nostr.js';

  interface Props {
    open: boolean;
    onSelect: (emoji: string) => void;
    onClose: () => void;
  }

  let { open, onSelect, onClose }: Props = $props();

  let emojis = $state<string[]>([]);
  let customEmojis = $state<Array<{ shortcode: string; url: string }>>([]);
  let searchQuery = $state('');
  let loadingCustomEmojis = $state(false);
  let uploading = $state(false);
  let uploadError: string | null = $state(null);
  let fileInput: HTMLInputElement | null = $state(null);
  let shortcodeInput: HTMLInputElement | null = $state(null);
  let showUploadForm = $state(false);

  // Check if user is logged in
  let isLoggedIn = $derived(sessionManager.isLoggedIn());

  // Common emojis to show first
  const commonEmojis = ['❤️', '🫂','😀', '😂', '😍', '🥰', '😎', '🤔', '👍', '🔥', '✨', '🎉', '💯', '👏', '🙏', '😊', '😢', '😮', '😴', '🤗', '😋'];

  // Debounce search
  let searchTimeout: ReturnType<typeof setTimeout> | null = null;

  function loadEmojis() {
    const allEmojis: string[] = [];
    
    // Add common emojis first
    allEmojis.push(...commonEmojis);
    
    // Add all other emojis
    for (let i = 0; i < emojiData.length; i++) {
      const emoji = emojiData[i];
      if (typeof emoji === 'string' && emoji.trim() && !commonEmojis.includes(emoji)) {
        allEmojis.push(emoji);
      }
    }
    
    emojis = allEmojis;
  }

  async function loadCustomEmojis() {
    loadingCustomEmojis = true;
    try {
      await loadAllEmojiPacks();
      const allEmojis = getAllCustomEmojis();
      console.debug(`[EmojiPicker] Loaded ${allEmojis.length} custom emojis`);
      customEmojis = allEmojis;
    } catch (error) {
      console.error('Error loading custom emojis:', error);
      customEmojis = [];
    } finally {
      loadingCustomEmojis = false;
    }
  }

  function handleSearchChange(query: string) {
    searchQuery = query;

    // Filter emojis
    if (searchTimeout) {
      clearTimeout(searchTimeout);
    }
    searchTimeout = setTimeout(async () => {
      if (!searchQuery.trim()) {
        loadEmojis();
        loadCustomEmojis();
        return;
      }
      
      const queryLower = searchQuery.toLowerCase().trim();
      
      // Filter Unicode emojis
      const allEmojis: string[] = [];
      allEmojis.push(...commonEmojis);
      for (let i = 0; i < emojiData.length; i++) {
        const emoji = emojiData[i];
        if (typeof emoji === 'string' && emoji.trim() && !commonEmojis.includes(emoji)) {
          allEmojis.push(emoji);
        }
      }
      
      // Filter by emoji name
      const filtered = allEmojis.filter(emoji => {
        // Search by emoji name using emojiNames lookup
        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(queryLower) || slug.includes(queryLower)) {
            return true;
          }
        }
        
        // Fallback: search the emoji character itself (though this rarely matches)
        return emoji.toLowerCase().includes(queryLower);
      });
      
      emojis = filtered;
      
      // Filter custom emojis by shortcode
      // Ensure custom emojis are loaded, then filter
      if (customEmojis.length === 0) {
        await loadCustomEmojis();
      }
      
      // Filter by shortcode
      const allCustomEmojis = getAllCustomEmojis();
      customEmojis = allCustomEmojis.filter(emoji => 
        emoji.shortcode.toLowerCase().includes(queryLower)
      );
    }, 200);
  }

  function handleCustomEmojiSelect(shortcode: string) {
    onSelect(`:${shortcode}:`);
    onClose();
  }

  // Convert file to data URL
  function fileToDataURL(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  }

  // Handle emoji file upload
  async function handleEmojiUpload(e: Event) {
    const target = e.target as HTMLInputElement;
    const files = target.files;
    if (!files || files.length === 0) return;

    const session = sessionManager.getSession();
    if (!session) {
      uploadError = 'Please log in to upload emojis';
      return;
    }

    uploading = true;
    uploadError = null;

    try {
      const relays = relayManager.getPublishRelays(
        [...relayManager.getThreadReadRelays(), ...relayManager.getFeedReadRelays()],
        true
      );

      // Fetch existing emoji set to merge with new emojis
      const existingRelays = relayManager.getProfileReadRelays();
      const existingEvents = await nostrClient.fetchEvents(
        [{ kinds: [KIND.EMOJI_SET], authors: [session.pubkey], limit: 1 }],
        existingRelays,
        { useCache: true, cacheResults: true }
      );

      // Collect existing emoji tags
      const existingEmojiTags: string[][] = [];
      if (existingEvents.length > 0) {
        for (const tag of existingEvents[0].tags) {
          if (tag[0] === 'emoji' && tag[1] && tag[2]) {
            existingEmojiTags.push(tag);
          }
        }
      }

      // Process each selected file
      const newEmojiTags: string[][] = [];
      const fileArray = Array.from(files);
      
      for (let i = 0; i < fileArray.length; i++) {
        const file = fileArray[i];
        
        // Verify it's an image
        if (!file.type.startsWith('image/')) {
          uploadError = `${file.name} is not an image file`;
          continue;
        }

        // Get shortcode: use input if single file, otherwise use filename
        let shortcode = '';
        if (fileArray.length === 1 && shortcodeInput && shortcodeInput.value.trim()) {
          shortcode = shortcodeInput.value.trim().toLowerCase().replace(/[^a-z0-9_+-]/g, '_');
        } else {
          // Use filename without extension for each file
          shortcode = file.name.replace(/\.[^/.]+$/, '').toLowerCase().replace(/[^a-z0-9_+-]/g, '_');
        }

        if (!shortcode) {
          uploadError = `Please provide a shortcode for ${file.name}`;
          continue;
        }

        // Check if shortcode already exists
        if (existingEmojiTags.some(tag => tag[1] === shortcode) || 
            newEmojiTags.some(tag => tag[1] === shortcode)) {
          // Append number if duplicate
          let counter = 1;
          let uniqueShortcode = `${shortcode}_${counter}`;
          while (existingEmojiTags.some(tag => tag[1] === uniqueShortcode) || 
                 newEmojiTags.some(tag => tag[1] === uniqueShortcode)) {
            counter++;
            uniqueShortcode = `${shortcode}_${counter}`;
          }
          shortcode = uniqueShortcode;
        }

        // Convert to data URL
        const dataUrl = await fileToDataURL(file);

        // Add emoji tag
        newEmojiTags.push(['emoji', shortcode, dataUrl]);
      }

      if (newEmojiTags.length === 0) {
        uploadError = 'No valid emojis to upload';
        return;
      }

      // Merge existing and new emoji tags
      const allEmojiTags = [...existingEmojiTags, ...newEmojiTags];

      // Create or update kind 10030 emoji set event
      const event: Omit<NostrEvent, 'sig' | 'id'> = {
        kind: KIND.EMOJI_SET,
        pubkey: session.pubkey,
        created_at: existingEvents.length > 0 
          ? existingEvents[0].created_at 
          : Math.floor(Date.now() / 1000),
        tags: allEmojiTags,
        content: ''
      };

      // Publish the event
      await signAndPublish(event, relays);

      // Reload custom emojis
      await loadCustomEmojis();
      
      // Reset form
      if (fileInput) fileInput.value = '';
      if (shortcodeInput) shortcodeInput.value = '';
      showUploadForm = false;
    } catch (error) {
      console.error('Error uploading emoji:', error);
      uploadError = error instanceof Error ? error.message : 'Failed to upload emoji';
    } finally {
      uploading = false;
    }
  }

  function triggerEmojiUpload() {
    if (showUploadForm) {
      fileInput?.click();
    } else {
      showUploadForm = true;
    }
  }

  // Load emojis when panel opens
  $effect(() => {
    if (open) {
      loadEmojis();
      loadCustomEmojis();
      searchQuery = '';
    }
  });
</script>

<EmojiDrawer
  {open}
  title="Choose Emoji"
  items={emojis}
  onSelect={onSelect}
  {onClose}
  onSearchChange={handleSearchChange}
>
  {#snippet children()}
    <div class="emoji-picker-wrapper">
      <div class="emoji-picker-content">
        {#if emojis.length === 0 && (!searchQuery.trim() || customEmojis.length === 0)}
          <div class="emoji-empty">No emojis found</div>
        {:else}
          {#if emojis.length > 0}
            <div class="emoji-grid">
              {#each emojis as emoji}
                <button
                  onclick={() => onSelect(emoji)}
                  class="emoji-item"
                  title="Click to insert emoji"
                >
                  {emoji}
                </button>
              {/each}
            </div>
          {/if}
          
          {#if customEmojis.length > 0}
            <div class="custom-emojis-section">
              <div class="custom-emojis-label">Custom</div>
              <div class="emoji-grid custom-emoji-grid">
                {#each customEmojis as emoji}
                  <button
                    onclick={() => handleCustomEmojiSelect(emoji.shortcode)}
                    class="emoji-item custom-emoji-item"
                    title=":{emoji.shortcode}:"
                  >
                    <img src={emoji.url} alt={emoji.shortcode} class="custom-emoji-img" />
                  </button>
                {/each}
              </div>
            </div>
          {/if}
          
          {#if loadingCustomEmojis && !searchQuery.trim()}
            <div class="emoji-empty">Loading custom emojis...</div>
          {/if}
        {/if}
      </div>
      
      <!-- Bottom option -->
      {#if isLoggedIn}
        <div class="emoji-picker-footer">
          {#if showUploadForm}
            <div class="emoji-upload-form">
              <input
                bind:this={shortcodeInput}
                type="text"
                placeholder="Shortcode (e.g., myemoji)"
                class="emoji-shortcode-input"
              />
              <button
                onclick={() => fileInput?.click()}
                class="emoji-footer-button"
                disabled={uploading}
              >
                {uploading ? 'Uploading...' : 'Select Image Files'}
              </button>
              <button
                onclick={() => { showUploadForm = false; uploadError = null; }}
                class="emoji-footer-button-close"
              >
                Cancel
              </button>
              <input
                bind:this={fileInput}
                type="file"
                accept="image/*"
                multiple
                onchange={handleEmojiUpload}
                style="display: none;"
              />
              {#if uploadError}
                <div class="emoji-upload-error">{uploadError}</div>
              {/if}
            </div>
          {:else}
            <button
              onclick={triggerEmojiUpload}
              class="emoji-footer-button"
            >
              Add your own Emojis
            </button>
          {/if}
        </div>
      {/if}
    </div>
  {/snippet}
</EmojiDrawer>

<style>
  .emoji-picker-wrapper {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }

  .emoji-picker-content {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    flex: 1;
    overflow-y: auto;
    min-height: 0;
  }

  .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-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
    gap: 0.5rem;
  }

  .custom-emoji-item {
    padding: 0.5rem;
    min-height: 3rem;
  }

  .custom-emoji-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: none !important;
  }

  .emoji-empty {
    text-align: center;
    padding: 2rem;
    color: var(--fog-text-light, #9ca3af);
    font-size: 0.875rem;
  }

  :global(.dark) .emoji-empty {
    color: var(--fog-dark-text-light, #6b7280);
  }

  .emoji-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(2.5rem, 1fr));
    gap: 0.25rem;
  }

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

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

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

  .emoji-picker-footer {
    padding: 1rem;
    border-top: 1px solid var(--fog-border, #e5e7eb);
    flex-shrink: 0;
  }

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

  .emoji-upload-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
  }

  .emoji-shortcode-input {
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.375rem;
    background: var(--fog-surface, #f8fafc);
    color: var(--fog-text, #1f2937);
    font-size: 0.875rem;
  }

  .emoji-shortcode-input:focus {
    outline: none;
    border-color: var(--fog-accent, #64748b);
    background: var(--fog-post, #ffffff);
  }

  :global(.dark) .emoji-shortcode-input {
    background: var(--fog-dark-surface, #1e293b);
    border-color: var(--fog-dark-border, #374151);
    color: var(--fog-dark-text, #f9fafb);
  }

  :global(.dark) .emoji-shortcode-input:focus {
    background: var(--fog-dark-post, #1f2937);
    border-color: var(--fog-dark-accent, #64748b);
  }

  .emoji-footer-button {
    padding: 0.5rem 1rem;
    background: var(--fog-accent, #64748b);
    color: white;
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.875rem;
    transition: opacity 0.2s;
  }

  .emoji-footer-button:hover:not(:disabled) {
    opacity: 0.9;
  }

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

  .emoji-footer-button-close {
    padding: 0.5rem 1rem;
    background: var(--fog-highlight, #f3f4f6);
    color: var(--fog-text, #1f2937);
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.875rem;
    transition: all 0.2s;
  }

  .emoji-footer-button-close:hover {
    background: var(--fog-border, #e5e7eb);
  }

  :global(.dark) .emoji-footer-button-close {
    background: var(--fog-dark-highlight, #374151);
    color: var(--fog-dark-text, #f9fafb);
  }

  :global(.dark) .emoji-footer-button-close:hover {
    background: var(--fog-dark-border, #475569);
  }

  .emoji-upload-error {
    color: var(--fog-error, #dc2626);
    font-size: 0.75rem;
    text-align: center;
  }

  :global(.dark) .emoji-upload-error {
    color: var(--fog-dark-error, #ef4444);
  }
</style>
