<script lang="ts">
  import FeedPost from '../feed/FeedPost.svelte';
  import CommentThread from '../comments/CommentThread.svelte';
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { loadEventIndex, type EventIndexItem, type MissingEventInfo } from '../../services/nostr/event-index-loader.js';
  import { onMount } from 'svelte';
  import type { NostrEvent } from '../../types/nostr.js';
  import { KIND } from '../../types/kind-lookup.js';
  import MetadataCard from '../../components/content/MetadataCard.svelte';

  interface Props {
    eventId: string;
    preloadedEvent?: NostrEvent | null; // Optional preloaded event to avoid re-fetching
  }

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

  // Virtual scrolling for kind 30040 (event indexes with 36k+ events)
  let Virtualizer: any = $state(null);
  let virtualizerLoading = $state(false);
  let virtualizerContainer = $state<HTMLElement | null>(null);
  
  async function loadVirtualizer() {
    if (Virtualizer) return Virtualizer;
    if (virtualizerLoading) return null;
    
    virtualizerLoading = true;
    try {
      const module = await import('@tanstack/svelte-virtual');
      Virtualizer = module.Virtualizer;
      return Virtualizer;
    } catch (error) {
      console.error('Failed to load virtual scrolling:', error);
      return null;
    } finally {
      virtualizerLoading = false;
    }
  }

  let rootEvent = $state<NostrEvent | null>(null);
  let loading = $state(true);
  let error = $state<string | null>(null);
  let lastLoadedEventId = $state<string | null>(null); // Track last loaded eventId to prevent loops
  
  // For kind 30040: event index hierarchy
  let isEventIndex = $derived(rootEvent?.kind === 30040);
  let eventIndexItems = $state<EventIndexItem[]>([]);
  let missingEvents = $state<MissingEventInfo[]>([]);
  let loadingIndex = $state(false);
  let indexError = $state<string | null>(null);
  
  // Count total items including nested ones for virtual scrolling decision
  function countTotalItems(items: EventIndexItem[]): number {
    let count = 0;
    for (const item of items) {
      count += 1;
      if (item.children && item.children.length > 0) {
        count += countTotalItems(item.children);
      }
    }
    return count;
  }
  
  let totalItemCount = $derived(countTotalItems(eventIndexItems));

  // Check if event is metadata-only (no content to display)
  // These kinds should only show metadata, not content
  const METADATA_ONLY_KINDS: number[] = [
    KIND.METADATA, // 0 - Profile metadata
    KIND.CONTACTS, // 3 - Contact list
    KIND.RELAY_LIST, // 10002 - Relay list metadata
    KIND.MUTE_LIST, // 10000 - Mute list
    KIND.BLOCKED_RELAYS, // 10006 - Blocked relays
    KIND.FAVORITE_RELAYS, // 10012 - Favorite relays
    KIND.LOCAL_RELAYS, // 10432 - Local relays
    KIND.PIN_LIST, // 10001 - Pin list
    KIND.BOOKMARKS, // 10003 - Bookmarks
    KIND.INTEREST_LIST, // 10015 - Interest list
    KIND.EMOJI_SET, // 10030 - Emoji set
    KIND.EMOJI_PACK, // 30030 - Emoji pack
    KIND.BADGES, // 30008 - Badges
    KIND.FOLLOW_SET, // 30000 - Follow set
    KIND.PAYMENT_ADDRESSES, // 10133 - Payment addresses
    KIND.LABEL, // 1985 - Label
    KIND.REPORT, // 1984 - Report
    KIND.HTTP_AUTH, // 27235 - HTTP Auth
    KIND.RSS_FEED, // 10895 - RSS Feed
    KIND.REPO_ANNOUNCEMENT, // 30617 - Repository announcement (metadata only)
    KIND.USER_STATUS, // 30315 - User status (metadata only, shown in profile)
  ];
  
  // Kinds that should render even with empty content (they have media or special rendering)
  const ALWAYS_RENDER_CONTENT_KINDS: number[] = [
    KIND.PICTURE_NOTE, // 20 - Has images in imeta tags
    KIND.VIDEO_NOTE, // 21 - Has videos in imeta tags
    KIND.SHORT_VIDEO_NOTE, // 22 - Has videos in imeta tags
    KIND.VOICE_NOTE, // 1222 - Has audio in imeta tags
    KIND.VOICE_REPLY, // 1244 - Has audio in imeta tags
    KIND.FILE_METADATA, // 1063 - Has files in tags
    KIND.POLL, // 1068 - Has poll rendering
    KIND.PUBLICATION_INDEX, // 30040 - Has children to render
    KIND.ISSUE, // 1621 - Repository issues (may have empty content but have tags)
    KIND.STATUS_OPEN, // 1630 - Status events
    KIND.STATUS_APPLIED, // 1631
    KIND.STATUS_CLOSED, // 1632
    KIND.STATUS_DRAFT, // 1633
  ];
  
  let isMetadataOnly = $derived(rootEvent ? (
    METADATA_ONLY_KINDS.includes(rootEvent.kind) ||
    (rootEvent.content === '' && 
     rootEvent.tags.length > 0 && 
     !ALWAYS_RENDER_CONTENT_KINDS.includes(rootEvent.kind))
  ) : false);

  onMount(async () => {
    await nostrClient.initialize();
    loadEvent();
  });

  $effect(() => {
    // Only load if eventId changed and we're not already loading
    // Also reload if preloadedEvent changes (e.g., from null to an actual event)
    if (eventId && eventId !== lastLoadedEventId && !loading) {
      loadEvent();
    } else if (preloadedEvent && preloadedEvent.id === eventId && !rootEvent && !loading) {
      // If we have a preloaded event and haven't loaded yet, use it immediately
      rootEvent = preloadedEvent;
      loading = false;
      if (preloadedEvent.kind === 30040) {
        loadEventIndexHierarchy(preloadedEvent);
        loadVirtualizer();
      }
    }
  });

  async function loadEvent() {
    // Prevent loading if already loading the same event
    if (loading && lastLoadedEventId === eventId) {
      return;
    }
    
    loading = true;
    error = null;
    indexError = null;
    eventIndexItems = [];
    rootEvent = null;
    lastLoadedEventId = eventId; // Track that we're loading this eventId
    
    try {
      // Use preloaded event if available and matches eventId
      let event: NostrEvent | null = null;
      if (preloadedEvent && preloadedEvent.id === eventId) {
        event = preloadedEvent;
      } else {
        // Load the event by ID
        const threadRelays = relayManager.getThreadReadRelays();
        const feedRelays = relayManager.getFeedReadRelays();
        const allRelays = [...new Set([...threadRelays, ...feedRelays])];
        event = await nostrClient.getEventById(eventId, allRelays);
      }
      
      if (event) {
        rootEvent = event;
        
        // If it's a kind 30040 event index, load the entire hierarchy
        if (event.kind === 30040) {
          await loadEventIndexHierarchy(event);
          // Load virtualizer for large lists
          await loadVirtualizer();
        }
      } else {
        error = 'Event not found';
      }
    } catch (err) {
      console.error('Error loading event:', err);
      error = err instanceof Error ? err.message : 'Failed to load event';
    } finally {
      loading = false;
    }
  }
  
  async function loadEventIndexHierarchy(opEvent: NostrEvent) {
    if (opEvent.kind !== 30040) return;
    
    loadingIndex = true;
    indexError = null;
    missingEvents = [];
    try {
      // console.log('Loading event index hierarchy for kind 30040...');
      const result = await loadEventIndex(opEvent);
      eventIndexItems = result.items;
      missingEvents = result.missingEvents;
      // console.log(`Loaded ${result.items.length} events from index hierarchy`);
      // Debug: log items with children
      // const itemsWithChildren = result.items.filter(item => item.children && item.children.length > 0);
      // console.log(`[EventView] Items with children: ${itemsWithChildren.length}`, itemsWithChildren.map(item => ({
      //   id: item.event.id,
      //   kind: item.event.kind,
      //   level: item.level,
      //   childrenCount: item.children?.length || 0,
      //   title: item.event.tags.find(t => t[0] === 'title')?.[1]
      // })));
      if (result.missingEvents.length > 0) {
        console.warn(`[EventView] ${result.missingEvents.length} events are missing from the index hierarchy`);
      }
    } catch (err) {
      console.error('Error loading event index:', err);
      indexError = err instanceof Error ? err.message : 'Failed to load event index';
    } finally {
      loadingIndex = false;
    }
  }
</script>

{#if loading}
  <p class="text-fog-text dark:text-fog-dark-text">Loading event...</p>
{:else if error}
  <p class="text-fog-text dark:text-fog-dark-text error-message">Error: {error}</p>
{:else if rootEvent}
  <article class="event-view">
    <!-- Display title and metadata for kind 30040 (book index) -->
    {#if rootEvent.kind === 30040}
      {@const titleTag = rootEvent.tags.find(t => t[0] === 'title')}
      {@const authorTag = rootEvent.tags.find(t => t[0] === 'author')}
      {@const typeTag = rootEvent.tags.find(t => t[0] === 'type')}
      {@const versionTag = rootEvent.tags.find(t => t[0] === 'version')}
      {@const publishedOnTag = rootEvent.tags.find(t => t[0] === 'published_on')}
      {@const publishedByTag = rootEvent.tags.find(t => t[0] === 'published_by')}
      {@const imageTag = rootEvent.tags.find(t => t[0] === 'image')}
      {@const summaryTag = rootEvent.tags.find(t => t[0] === 'summary')}
      {@const sourceTag = rootEvent.tags.find(t => t[0] === 'source')}
      {@const iTags = rootEvent.tags.filter(t => t[0] === 'i')}
      {@const tTags = rootEvent.tags.filter(t => t[0] === 't')}
      {@const pTag = rootEvent.tags.find(t => t[0] === 'p')}
      {@const ETag = rootEvent.tags.find(t => t[0] === 'E')}
      
      {#if titleTag && titleTag[1]}
        <h1 class="book-title text-3xl font-bold mb-6 text-fog-text dark:text-fog-dark-text">
          {titleTag[1]}
        </h1>
      {/if}
      
      <!-- Publication metadata -->
      <div class="publication-metadata mb-6 space-y-2">
        {#if authorTag && authorTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Author:</span> {authorTag[1]}
          </p>
        {/if}
        
        {#if typeTag && typeTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Type:</span> {typeTag[1]}
          </p>
        {/if}
        
        {#if versionTag && versionTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Version:</span> {versionTag[1]}
          </p>
        {/if}
        
        {#if publishedOnTag && publishedOnTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Published:</span> {publishedOnTag[1]}
            {#if publishedByTag && publishedByTag[1]}
              <span> by {publishedByTag[1]}</span>
            {/if}
          </p>
        {:else if publishedByTag && publishedByTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Published by:</span> {publishedByTag[1]}
          </p>
        {/if}
        
        {#if iTags.length > 0}
          {@const plural = iTags.length > 1 ? 's' : ''}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Identifier{plural}:</span>
            {#each iTags as iTag, index}
              {iTag[1]}{#if index < iTags.length - 1}, {/if}
            {/each}
          </p>
        {/if}
        
        {#if tTags.length > 0}
          {@const plural = tTags.length > 1 ? 's' : ''}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Topic{plural}:</span>
            {#each tTags as tTag}
              <span class="topic-tag">{tTag[1]}</span>
            {/each}
          </p>
        {/if}
        
        {#if sourceTag && sourceTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text">
            <span class="font-semibold">Source:</span> 
            <a href={sourceTag[1]} target="_blank" rel="noopener noreferrer" class="text-blue-600 dark:text-blue-400 hover:underline">
              {sourceTag[1]}
            </a>
          </p>
        {/if}
        
        {#if summaryTag && summaryTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text mt-4">
            {summaryTag[1]}
          </p>
        {/if}
        
        {#if imageTag && imageTag[1]}
          <div class="publication-cover-image mt-4">
            <img src={imageTag[1]} alt="Cover image for {titleTag?.[1] || 'publication'}" class="max-w-md rounded-lg shadow-lg" />
          </div>
        {/if}
        
        {#if pTag && pTag[1]}
          <p class="text-fog-text dark:text-fog-dark-text mt-4 text-sm italic">
            <span class="font-semibold">Original author:</span> 
            <a href="/profile/{pTag[1]}" class="text-blue-600 dark:text-blue-400 hover:underline">
              {pTag[1]}
            </a>
            {#if ETag && ETag[1]}
              <span> (derivative work)</span>
            {/if}
          </p>
        {/if}
      </div>
    {/if}
    
    <!-- Display metadata-only events with MetadataCard -->
    {#if isMetadataOnly}
      <div class="metadata-section">
        <MetadataCard event={rootEvent} />
      </div>
    {:else if isEventIndex}
      <!-- For kind 30040: Display event index hierarchy with virtual scrolling -->
      <div class="event-index-section">
        {#if loadingIndex}
          <p class="text-fog-text dark:text-fog-dark-text">Loading event index hierarchy... ({eventIndexItems.length} loaded so far)</p>
        {:else if indexError}
          <p class="text-fog-text dark:text-fog-dark-text error-message">Error: {indexError}</p>
        {:else if eventIndexItems.length === 0 && missingEvents.length === 0}
          <p class="text-fog-text dark:text-fog-dark-text">No events found in index</p>
        {:else}
          <!-- Display missing events first -->
          {#if missingEvents.length > 0}
            <div class="missing-events-section mb-4">
              {#each missingEvents as missing (missing.order)}
                <div class="missing-event-message">
                  <p class="text-fog-text dark:text-fog-dark-text">
                    This event <code class="d-tag-code">{missing.dTag}</code> is missing.
                  </p>
                </div>
              {/each}
            </div>
          {/if}
          
          {#if eventIndexItems.length > 0}
            <!-- Recursive rendering function for nested structures -->
            {#snippet renderIndexItems(items: EventIndexItem[], parentLevel: number = 0)}
              {#each items as item (item.event.id)}
                <div class="event-index-item" data-index={item.order} data-level={item.level}>
                  <!-- Display title for kind 30040 indexes (chapter/subchapter indexes) -->
                  {#if item.event.kind === 30040}
                    {@const indexTitleTag = item.event.tags.find(t => t[0] === 'title')}
                    {#if indexTitleTag && indexTitleTag[1]}
                      {@const headingLevel = Math.min(2 + item.level, 6)}
                      {@const textSize = item.level === 0 ? 'xl' : item.level === 1 ? 'lg' : 'base'}
                      {#if headingLevel === 2}
                        <h2 class="index-title text-{textSize} font-semibold mb-3 mt-4 text-fog-text dark:text-fog-dark-text">
                          {indexTitleTag[1]}
                        </h2>
                      {:else if headingLevel === 3}
                        <h3 class="index-title text-{textSize} font-semibold mb-3 mt-4 text-fog-text dark:text-fog-dark-text">
                          {indexTitleTag[1]}
                        </h3>
                      {:else if headingLevel === 4}
                        <h4 class="index-title text-{textSize} font-semibold mb-3 mt-4 text-fog-text dark:text-fog-dark-text">
                          {indexTitleTag[1]}
                        </h4>
                      {:else if headingLevel === 5}
                        <h5 class="index-title text-{textSize} font-semibold mb-3 mt-4 text-fog-text dark:text-fog-dark-text">
                          {indexTitleTag[1]}
                        </h5>
                      {:else}
                        <h6 class="index-title text-{textSize} font-semibold mb-3 mt-4 text-fog-text dark:text-fog-dark-text">
                          {indexTitleTag[1]}
                        </h6>
                      {/if}
                    {/if}
                    
                    <!-- Recursively render children of kind 30040 indexes -->
                    {#if item.children && item.children.length > 0}
                      <div class="nested-index" style="margin-left: {item.level * 1.5}rem; margin-top: 1rem;">
                        {@render renderIndexItems(item.children, item.level)}
                      </div>
                    {/if}
                  {:else}
                    <!-- For content events (not kind 30040 indexes), render the content -->
                    <!-- Display chapter title prominently for kind 30041 (chapter sections) -->
                    {#if item.event.kind === 30041 || item.event.kind === 1 || item.event.kind === 30817}
                      {@const chapterTitleTag = item.event.tags.find(t => t[0] === 'title')}
                      {#if chapterTitleTag && chapterTitleTag[1]}
                        <h2 class="chapter-title text-xl font-semibold mb-3 text-fog-text dark:text-fog-dark-text">
                          {chapterTitleTag[1]}
                        </h2>
                      {/if}
                    {/if}
                    
                    <!-- Render the event content -->
                    <div class="event-with-comments">
                      <!-- Hide title in FeedPost since we're already showing it above as chapter-title -->
                      <FeedPost post={item.event} fullView={true} hideTitle={true} />
                      
                      <!-- Load and display comments for each event in the index -->
                      <div class="comments-section mt-4">
                        <CommentThread threadId={item.event.id} event={item.event} />
                      </div>
                    </div>
                    
                    <!-- Recursively render children if this content event has nested children -->
                    {#if item.children && item.children.length > 0}
                      <div class="nested-index" style="margin-left: {item.level * 1.5}rem; margin-top: 1rem;">
                        {@render renderIndexItems(item.children, item.level)}
                      </div>
                    {/if}
                  {/if}
                </div>
              {/each}
            {/snippet}
            
            <!-- Note: Virtual scrolling doesn't work well with nested structures, so we disable it for nested indexes -->
            {#if Virtualizer && totalItemCount > 100 && eventIndexItems.every(item => !item.children || item.children.length === 0)}
              <!-- Use virtual scrolling only for flat lists (100+ items, no nesting) -->
              {#if Virtualizer}
                {@const V = Virtualizer}
                <div bind:this={virtualizerContainer} class="virtual-scroll-container" style="height: 80vh; overflow: auto;">
                  <V
                    count={eventIndexItems.length}
                    getScrollElement={() => virtualizerContainer}
                    estimateSize={() => 200}
                    overscan={5}
                  >
                    {@render renderIndexItems(eventIndexItems)}
                  </V>
                </div>
              {/if}
            {:else}
              <!-- Progressive rendering for smaller lists or nested structures -->
              <div class="event-index-list">
                {@render renderIndexItems(eventIndexItems)}
              </div>
            {/if}
          {/if}
        {/if}
      </div>
    {:else}
      <!-- Display regular events using FeedPost -->
      <div class="event-section">
        <FeedPost post={rootEvent} fullView={true} hideTitle={false} />
      </div>
      
      <!-- Load and display comments for all event types -->
      {#if rootEvent && !isMetadataOnly}
        <div class="comments-section mt-6">
          <CommentThread threadId={rootEvent.id} event={rootEvent} />
        </div>
      {/if}
    {/if}
  </article>
{:else}
  <p class="text-fog-text dark:text-fog-dark-text">Event not found</p>
{/if}

<style>
  .event-view {
    max-width: var(--content-width);
    margin: 0 auto;
    padding: 1rem;
  }

  .metadata-section {
    margin-bottom: 2rem;
  }

  .event-section {
    margin-bottom: 2rem;
  }

  .event-index-section {
    margin-top: 2rem;
  }

  .virtual-scroll-container {
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.5rem;
    padding: 1rem;
  }

  :global(.dark) .virtual-scroll-container {
    border-color: var(--fog-dark-border, #374151);
  }

  .event-index-item {
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
  }

  .event-index-item:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
  }

  .book-title {
    margin-top: 1rem;
    margin-bottom: 2rem;
    padding-bottom: 1rem;
    border-bottom: 2px solid var(--fog-border, #e5e7eb);
  }

  :global(.dark) .book-title {
    border-bottom-color: var(--fog-dark-border, #374151);
  }

  .publication-metadata {
    padding: 1rem;
    background: var(--fog-bg-secondary, #f9fafb);
    border-radius: 0.5rem;
    border: 1px solid var(--fog-border, #e5e7eb);
  }

  :global(.dark) .publication-metadata {
    background: var(--fog-dark-bg-secondary, #1f2937);
    border-color: var(--fog-dark-border, #374151);
  }

  .topic-tag {
    display: inline-block;
    padding: 0.25rem 0.5rem;
    margin: 0.125rem;
    background: var(--fog-accent, #3b82f6);
    color: white;
    border-radius: 0.25rem;
    font-size: 0.875rem;
  }

  :global(.dark) .topic-tag {
    background: var(--fog-dark-accent, #2563eb);
  }

  .publication-cover-image {
    margin-top: 1rem;
  }

  .publication-cover-image img {
    max-width: 100%;
    height: auto;
  }

  .chapter-title {
    margin-top: 1.5rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
  }

  .chapter-title:first-child {
    margin-top: 0;
  }

  :global(.dark) .chapter-title {
    border-bottom-color: var(--fog-dark-border, #374151);
  }

  .index-title {
    margin-top: 1.5rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--fog-border, #e5e7eb);
  }

  .index-title:first-child {
    margin-top: 0;
  }

  :global(.dark) .index-title {
    border-bottom-color: var(--fog-dark-border, #374151);
  }

  .nested-index {
    border-left: 2px solid var(--fog-border, #e5e7eb);
    padding-left: 1rem;
    margin-top: 0.5rem;
  }

  :global(.dark) .nested-index {
    border-left-color: var(--fog-dark-border, #374151);
  }

  .event-index-item[data-level="1"] {
    margin-left: 0.5rem;
  }

  .event-index-item[data-level="2"] {
    margin-left: 1rem;
  }

  .event-index-item[data-level="3"] {
    margin-left: 1.5rem;
  }

  :global(.dark) .event-index-item {
    border-bottom-color: var(--fog-dark-border, #374151);
  }

  .event-index-list {
    max-height: none;
  }

  .error-message {
    color: var(--fog-error, #ef4444);
    padding: 1rem;
    background: var(--fog-error-bg, #fee2e2);
    border-radius: 0.5rem;
  }

  :global(.dark) .error-message {
    background: var(--fog-dark-error-bg, #7f1d1d);
  }

  .missing-events-section {
    padding: 1rem;
    background: var(--fog-warning-bg, #fef3c7);
    border: 1px solid var(--fog-warning-border, #fbbf24);
    border-radius: 0.5rem;
    margin-bottom: 1rem;
  }

  :global(.dark) .missing-events-section {
    background: var(--fog-dark-warning-bg, #78350f);
    border-color: var(--fog-dark-warning-border, #d97706);
  }

  .missing-event-message {
    margin-bottom: 0.5rem;
  }

  .missing-event-message:last-child {
    margin-bottom: 0;
  }

  .d-tag-code {
    font-family: monospace;
    background: var(--fog-code-bg, #f3f4f6);
    padding: 0.125rem 0.25rem;
    border-radius: 0.25rem;
    font-size: 0.875rem;
  }

  :global(.dark) .d-tag-code {
    background: var(--fog-dark-code-bg, #374151);
  }
</style>
