<script lang="ts">
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { onMount } from 'svelte';
  import { nip19 } from 'nostr-tools';
  import type { NostrEvent } from '../../types/nostr.js';
  import { stripMarkdown } from '../../services/text-utils.js';
  import ProfileBadge from '../layout/ProfileBadge.svelte';
  import { KIND } from '../../types/kind-lookup.js';

  interface Props {
    eventId: string; // Can be hex, note, nevent, naddr
  }

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

  let event = $state<NostrEvent | null>(null);
  let loading = $state(true);
  let error = $state(false);
  let loadingEvent = $state(false);
  let lastEventId = $state<string | null>(null);

  onMount(async () => {
    if (eventId && eventId !== lastEventId) {
      await loadEvent();
    }
  });

  $effect(() => {
    if (eventId && eventId !== lastEventId && !loadingEvent) {
      lastEventId = eventId;
      loadEvent();
    }
  });

  // Validate if a string is a valid bech32 or hex string
  function isValidNostrId(str: string): boolean {
    if (!str || typeof str !== 'string') return false;
    // Check for HTML tags or other invalid characters
    if (/<[^>]+>/.test(str)) return false;
    // Check if it's hex (64 hex characters)
    if (/^[0-9a-f]{64}$/i.test(str)) return true;
    // Check if it's bech32 (npub1..., note1..., nevent1..., naddr1..., nprofile1...)
    if (/^(npub|note|nevent|naddr|nprofile)1[a-z0-9]+$/.test(str)) return true;
    return false;
  }

  async function loadEvent() {
    // Prevent concurrent loads for the same event
    if (loadingEvent) {
      return;
    }
    loadingEvent = true;
    loading = true;
    error = false;
    try {
      // Validate eventId before processing
      if (!eventId || !isValidNostrId(eventId)) {
        console.warn('Invalid event ID format:', eventId);
        error = true;
        loading = false;
        loadingEvent = false;
        return;
      }

      // Decode event ID
      let hexId: string | null = null;
      
      // Check if it's already hex
      if (/^[0-9a-f]{64}$/i.test(eventId)) {
        hexId = eventId.toLowerCase();
      } else {
        // Try to decode bech32
        try {
          const decoded = nip19.decode(eventId);
          if (decoded.type === 'note') {
            hexId = String(decoded.data);
          } else if (decoded.type === 'nevent' && decoded.data && typeof decoded.data === 'object' && 'id' in decoded.data) {
            hexId = String(decoded.data.id);
          } else if (decoded.type === 'naddr' && decoded.data && typeof decoded.data === 'object') {
            // For naddr, fetch by kind+pubkey+d tag
            const naddrData = decoded.data as { kind: number; pubkey: string; identifier?: string; relays?: string[] };
            if (naddrData.kind && naddrData.pubkey) {
              const dTag = naddrData.identifier || '';
              const threadRelays = relayManager.getThreadReadRelays();
              const feedRelays = relayManager.getFeedReadRelays();
              const allRelays = [...new Set([...threadRelays, ...feedRelays, ...(naddrData.relays || [])])];
              
              // Fetch parameterized replaceable event
              const filter: any = {
                kinds: [naddrData.kind],
                authors: [naddrData.pubkey],
                '#d': [dTag],
                limit: 1
              };
              
              const events = await nostrClient.fetchEvents([filter], allRelays, { useCache: true, cacheResults: true });
              if (events.length > 0) {
                event = events[0];
                loading = false;
                return;
              } else {
                error = true;
                loading = false;
                return;
              }
            } else {
              error = true;
              loading = false;
              return;
            }
          }
        } catch (e) {
          console.error('Failed to decode event ID:', e);
          error = true;
          loading = false;
          loadingEvent = false;
          return;
        }
      }

      if (!hexId) {
        error = true;
        loading = false;
        loadingEvent = false;
        return;
      }

      // Validate hexId is exactly 64 characters (proper event ID length)
      if (hexId.length !== 64 || !/^[0-9a-f]{64}$/i.test(hexId)) {
        console.warn('Invalid hex event ID length or format:', hexId);
        error = true;
        loading = false;
        loadingEvent = false;
        return;
      }

      const relays = relayManager.getThreadReadRelays();
      const feedRelays = relayManager.getFeedReadRelays();
      const allRelays = [...new Set([...relays, ...feedRelays])];
      
      const loadedEvent = await nostrClient.getEventById(hexId, allRelays);
      event = loadedEvent;
    } catch (err) {
      console.error('Error loading embedded event:', err);
      error = true;
    } finally {
      loading = false;
      loadingEvent = false;
    }
  }

  function getTitle(): string {
    if (!event) return '';
    if (event.kind === KIND.DISCUSSION_THREAD) {
      const titleTag = event.tags.find(t => t[0] === 'title');
      return titleTag?.[1] || '';
    }
    // For other event kinds, don't use content as title - leave it blank
    return '';
  }

  function getSubject(): string | null {
    if (!event) return null;
    const subjectTag = event.tags.find(t => t[0] === 'subject');
    return subjectTag?.[1] || null;
  }

  function getImageUrl(): string | null {
    if (!event) return null;
    const imageTag = event.tags.find(t => t[0] === 'image');
    return imageTag?.[1] || null;
  }

  // Extract image URLs from event content
  function getImageUrlsFromContent(): string[] {
    if (!event) return [];
    const imageUrls: string[] = [];
    const imageExtensions = /\.(png|jpg|jpeg|gif|webp|svg|bmp|ico)(\?[^\s<>"']*)?$/i;
    const urlPattern = /https?:\/\/[^\s<>"']+/g;
    
    let match;
    while ((match = urlPattern.exec(event.content)) !== null) {
      const url = match[0];
      if (imageExtensions.test(url)) {
        // Check if it's not already in markdown or HTML
        const before = event.content.substring(Math.max(0, match.index - 10), match.index);
        const after = event.content.substring(match.index + url.length, Math.min(event.content.length, match.index + url.length + 10));
        if (!before.includes('![') && !before.includes('<img') && !after.startsWith('](') && !after.startsWith('</img>')) {
          imageUrls.push(url);
        }
      }
    }
    
    return imageUrls;
  }

  function getPreview(): string {
    if (!event) return '';
    // Remove image URLs from preview text
    let preview = event.content;
    const imageUrls = getImageUrlsFromContent();
    for (const url of imageUrls) {
      preview = preview.replace(url, '').trim();
    }
    preview = stripMarkdown(preview).slice(0, 150);
    return preview.length < event.content.length ? preview + '...' : preview;
  }

  function handleClick(e: MouseEvent) {
    e.preventDefault();
    if (!event) return;
    
    // Dispatch custom event on window to open in side-panel
    // Parent components (like FeedPage, DiscussionList) listen for this event on window
    const openEvent = new CustomEvent('openEventInDrawer', {
      detail: { event },
      bubbles: true,
      cancelable: true
    });
    
    window.dispatchEvent(openEvent);
  }
</script>

{#if loading}
  <div class="embedded-event loading">
    <span class="text-fog-text-light dark:text-fog-dark-text-light">Loading event...</span>
  </div>
{:else if error}
  <div class="embedded-event error">
    <span class="text-fog-text-light dark:text-fog-dark-text-light">Failed to load event</span>
  </div>
{:else if event}
  <div class="embedded-event" onclick={handleClick} role="button" tabindex="0" onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleClick(e as any); } }}>
    {#if getImageUrl()}
      <div class="embedded-event-image">
        <img src={getImageUrl()} alt={getTitle()} loading="lazy" />
      </div>
    {:else}
      {@const contentImages = getImageUrlsFromContent()}
      {#if contentImages.length > 0}
        <div class="embedded-event-images">
          {#each contentImages.slice(0, 3) as imageUrl}
            <div class="embedded-event-image">
              <img src={imageUrl} alt={getTitle()} loading="lazy" />
            </div>
          {/each}
        </div>
      {/if}
    {/if}
    <div class="embedded-event-content">
      <div class="embedded-event-header">
        {#if getTitle()}
          <h4 class="embedded-event-title">{getTitle()}</h4>
        {/if}
        {#if event}
          <ProfileBadge pubkey={event.pubkey} />
        {/if}
      </div>
      {#if getSubject()}
        <p class="embedded-event-subject">{getSubject()}</p>
      {/if}
      <p class="embedded-event-preview">{getPreview()}</p>
    </div>
  </div>
{/if}

<style>
  .embedded-event {
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.5rem;
    padding: 1rem;
    margin: 0.5rem 0;
    cursor: pointer;
    transition: background-color 0.2s;
    background: var(--fog-post, #ffffff);
  }

  :global(.dark) .embedded-event {
    border-color: var(--fog-dark-border, #374151);
    background: var(--fog-dark-post, #1f2937);
  }

  .embedded-event:hover {
    background: var(--fog-highlight, #f1f5f9);
  }

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

  .embedded-event-image {
    width: 100%;
    max-height: 200px;
    overflow: hidden;
    border-radius: 0.25rem;
    margin-bottom: 0.75rem;
  }

  .embedded-event-image img {
    width: 100%;
    height: auto;
    object-fit: cover;
  }

  .embedded-event-images {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
  }

  .embedded-event-images .embedded-event-image {
    margin-bottom: 0;
  }

  .embedded-event-content {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .embedded-event-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    line-height: 1.5;
  }
  
  .embedded-event-header :global(.profile-badge) {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    line-height: 1.5;
  }

  .embedded-event-title {
    font-weight: 600;
    font-size: 1.125rem;
    margin: 0;
    line-height: 1.5;
    color: var(--fog-text, #1f2937);
    display: inline-block;
    vertical-align: middle;
  }

  :global(.dark) .embedded-event-title {
    color: var(--fog-dark-text, #f9fafb);
  }

  .embedded-event-subject {
    font-size: 0.875rem;
    color: var(--fog-text-light, #64748b);
    margin: 0;
  }

  :global(.dark) .embedded-event-subject {
    color: var(--fog-dark-text-light, #9ca3af);
  }

  .embedded-event-preview {
    font-size: 0.875rem;
    color: var(--fog-text, #475569);
    margin: 0;
    line-height: 1.5;
  }

  :global(.dark) .embedded-event-preview {
    color: var(--fog-dark-text, #cbd5e1);
  }


  .embedded-event.loading,
  .embedded-event.error {
    padding: 1rem;
    text-align: center;
  }
</style>
