<script lang="ts">
  import { nip19 } from 'nostr-tools';
  import type { NostrEvent } from '../types/nostr.js';
  import { nostrClient } from '../services/nostr/nostr-client.js';
  import { relayManager } from '../services/nostr/relay-manager.js';
  import EventJsonModal from './modals/EventJsonModal.svelte';
  import PublicationStatusModal from './modals/PublicationStatusModal.svelte';
  import { 
    isPinned, 
    isBookmarked, 
    isHighlighted, 
    togglePin, 
    toggleBookmark, 
    toggleHighlight 
  } from '../services/user-actions.js';
  import { eventMenuStore } from '../services/event-menu-store.js';
  import { sessionManager } from '../services/auth/session-manager.js';
  import { signAndPublish } from '../services/nostr/auth-handler.js';
  import RelatedEventsModal from './modals/RelatedEventsModal.svelte';
  import { KIND } from '../types/kind-lookup.js';
  import { goto } from '$app/navigation';

  interface Props {
    event: NostrEvent;
    showContentActions?: boolean; // Show pin/bookmark/highlight for notes with content
    onReply?: () => void; // Callback for reply action
  }

  let { event, showContentActions = false, onReply }: Props = $props();

  let menuOpen = $state(false);
  let jsonModalOpen = $state(false);
  let relatedEventsModalOpen = $state(false);
  let publicationModalOpen = $state(false);
  let publicationResults = $state<{ success: string[]; failed: Array<{ relay: string; error: string }> } | null>(null);
  let broadcasting = $state(false);
  let deleting = $state(false);
  let deleteConfirmOpen = $state(false);
  let copied = $state<string | null>(null);
  let menuButtonElement: HTMLButtonElement | null = $state(null);
  let menuDropdownElement: HTMLDivElement | null = $state(null);
  let menuPosition = $state({ top: 0, right: 0 });
  
  // Unique ID for this menu instance
  let menuId = $derived(event.id);

  // Note: Removed isContentNote check - all events should have the same menu (except profile pages/cards)
  
  // Check if user is logged in
  let isLoggedIn = $derived(sessionManager.isLoggedIn());
  let currentUserPubkey = $derived(sessionManager.getCurrentPubkey());
  let isOwnEvent = $derived(isLoggedIn && currentUserPubkey === event.pubkey);

  // Track pin/bookmark/highlight state
  let pinnedState = $state(false);
  let bookmarkedState = $state(false);
  let highlightedState = $state(false);
  let stateUpdateTrigger = $state(0); // Trigger to force state updates

  // Update state when event changes or when trigger changes
  $effect(() => {
    highlightedState = isHighlighted(event.id);
    // Access trigger to make effect reactive to it
    void stateUpdateTrigger;
    
    // Update pin and bookmark state asynchronously
    isPinned(event.id).then(pinned => {
      pinnedState = pinned;
    });
    isBookmarked(event.id).then(bookmarked => {
      bookmarkedState = bookmarked;
    });
  });

  function toggleMenu() {
    if (menuOpen) {
      closeMenu();
    } else {
      openMenu();
    }
  }

  function openMenu() {
    menuOpen = true;
    // Register this menu as open - this will close any other open menu
    eventMenuStore.openMenu(menuId, closeMenu);
    // Position menu after opening
    requestAnimationFrame(() => {
      positionMenu();
    });
  }

  function positionMenu() {
    if (!menuButtonElement || !menuDropdownElement) return;

    const buttonRect = menuButtonElement.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const padding = 8; // Padding from viewport edges
    
    // Get dropdown dimensions (estimate or use actual if available)
    let dropdownWidth = 200; // min-width from CSS
    let dropdownHeight = 300; // Estimate, will be updated
    
    // Position below button by default, aligned to right edge
    let top = buttonRect.bottom + 4;
    let right = viewportWidth - buttonRect.right;
    
    // Get actual dimensions after rendering
    requestAnimationFrame(() => {
      if (!menuDropdownElement) return;
      const dropdownRect = menuDropdownElement.getBoundingClientRect();
      dropdownWidth = dropdownRect.width;
      dropdownHeight = dropdownRect.height;
      
      // Calculate left position from right
      const left = viewportWidth - right - dropdownWidth;
      
      // Check and adjust for viewport boundaries
      let adjustedTop = top;
      let adjustedRight = right;
      
      // Check bottom overflow
      if (top + dropdownHeight + padding > viewportHeight) {
        // Try positioning above button
        const spaceAbove = buttonRect.top;
        const spaceBelow = viewportHeight - buttonRect.bottom;
        if (spaceAbove >= dropdownHeight + padding || spaceAbove > spaceBelow) {
          adjustedTop = buttonRect.top - dropdownHeight - 4;
        } else {
          // Not enough space above, position at bottom of viewport
          adjustedTop = viewportHeight - dropdownHeight - padding;
        }
      }
      
      // Check top overflow
      if (adjustedTop < padding) {
        adjustedTop = padding;
      }
      
      // Check right overflow (menu goes off right edge)
      if (left < padding) {
        adjustedRight = viewportWidth - padding - dropdownWidth;
      }
      
      // Check left overflow (menu goes off left edge)
      const adjustedLeft = viewportWidth - adjustedRight - dropdownWidth;
      if (adjustedLeft < padding) {
        adjustedRight = viewportWidth - padding - dropdownWidth;
      }
      
      // Ensure menu doesn't go off right edge
      if (adjustedRight < padding) {
        adjustedRight = padding;
      }
      
      menuPosition = { top: adjustedTop, right: adjustedRight };
    });
    
    // Set initial position
    menuPosition = { top, right };
  }

  function closeMenu() {
    menuOpen = false;
    eventMenuStore.closeMenu(menuId);
  }

  // Close menu when clicking outside
  function handleClickOutside(e: MouseEvent) {
    const target = e.target as HTMLElement;
    if (!target.closest('.event-menu-container') && !target.closest('.menu-dropdown')) {
      eventMenuStore.closeCurrentMenu();
    }
  }

  $effect(() => {
    if (menuOpen) {
      document.addEventListener('click', handleClickOutside);
      window.addEventListener('scroll', closeMenu, true);
      window.addEventListener('resize', positionMenu);
      // Reposition on scroll to keep menu aligned
      const handleScroll = () => {
        if (menuOpen) {
          positionMenu();
        }
      };
      window.addEventListener('scroll', handleScroll, true);
      return () => {
        document.removeEventListener('click', handleClickOutside);
        window.removeEventListener('scroll', closeMenu, true);
        window.removeEventListener('resize', positionMenu);
        window.removeEventListener('scroll', handleScroll, true);
      };
    }
  });

  async function copyUserId() {
    try {
      const npub = nip19.npubEncode(event.pubkey);
      await navigator.clipboard.writeText(npub);
      copied = 'npub';
      setTimeout(() => {
        copied = null;
      }, 2000);
      closeMenu();
    } catch (error) {
      console.error('Failed to copy user ID:', error);
    }
  }

  async function copyEventId() {
    try {
      const nevent = nip19.neventEncode({
        id: event.id,
        relays: []
      });
      await navigator.clipboard.writeText(nevent);
      copied = 'nevent';
      setTimeout(() => {
        copied = null;
      }, 2000);
      closeMenu();
    } catch (error) {
      console.error('Failed to copy event ID:', error);
    }
  }

  function viewJson() {
    jsonModalOpen = true;
    closeMenu();
  }

  function viewRelatedEvents() {
    relatedEventsModalOpen = true;
    closeMenu();
  }

  async function broadcastEvent() {
    broadcasting = true;
    closeMenu();
    
    try {
      // Get all available relays for broadcasting
      const relays = relayManager.getPublishRelays(
        [...relayManager.getThreadReadRelays(), ...relayManager.getFeedReadRelays()],
        true
      );
      
      const results = await nostrClient.publish(event, { relays });
      publicationResults = results;
      publicationModalOpen = true;
    } catch (error) {
      console.error('Error broadcasting event:', error);
      publicationResults = {
        success: [],
        failed: [{ relay: 'Unknown', error: error instanceof Error ? error.message : 'Unknown error' }]
      };
      publicationModalOpen = true;
    } finally {
      broadcasting = false;
    }
  }

  async function shareWithaitherboard() {
    try {
      const url = `${window.location.origin}/event/${event.id}`;
      await navigator.clipboard.writeText(url);
      copied = 'share';
      setTimeout(() => {
        copied = null;
      }, 2000);
      closeMenu();
    } catch (error) {
      console.error('Failed to copy share URL:', error);
    }
  }

  async function pinNote() {
    await togglePin(event.id);
    // Force state update
    stateUpdateTrigger++;
    closeMenu();
  }

  async function bookmarkNote() {
    await toggleBookmark(event.id);
    // Force state update by re-checking bookmark status
    const newBookmarked = await isBookmarked(event.id);
    bookmarkedState = newBookmarked;
    closeMenu();
  }

  function highlightNote() {
    // Extract content and e/a tags for highlight
    const content = event.content || '';
    
    // Collect all relevant tags: e-tag with the event's ID, a-tag (if available), and p-tag with the event's pubkey
    const tagsToInclude: string[][] = [];
    
    // Always add e-tag with the event ID of the event being highlighted
    tagsToInclude.push(['e', event.id]);
    
    // Also check for a-tag in the original event (for parameterized replaceable events)
    const aTag = event.tags.find(tag => tag[0] === 'a');
    if (aTag) {
      tagsToInclude.push(aTag);
    }
    
    // Add p-tag with the pubkey of the event being highlighted
    tagsToInclude.push(['p', event.pubkey]);
    
    // Store highlight data in sessionStorage
    const highlightData = {
      content,
      tags: tagsToInclude
    };
    sessionStorage.setItem('aitherboard_highlightData', JSON.stringify(highlightData));
    
    // Navigate to write form with kind 9802 (highlight)
    goto('/write?kind=9802');
    closeMenu();
  }

  function confirmDelete() {
    deleteConfirmOpen = true;
    closeMenu();
  }

  async function deleteEvent() {
    if (!isLoggedIn) return;
    
    deleting = true;
    deleteConfirmOpen = false;
    
    try {
      // Create kind 5 deletion event
      const deletionEvent: Omit<NostrEvent, 'sig' | 'id'> = {
        kind: KIND.EVENT_DELETION,
        pubkey: currentUserPubkey!, // Use the current user's pubkey (the person deleting)
        created_at: Math.floor(Date.now() / 1000),
        tags: [['e', event.id]], // Reference the deleted event
        content: ''
      };
      
      // Get all available relays for publishing
      const relays = relayManager.getPublishRelays(
        [...relayManager.getThreadReadRelays(), ...relayManager.getFeedReadRelays()],
        true
      );
      
      // Sign and publish
      const results = await signAndPublish(deletionEvent, relays);
      publicationResults = results;
      publicationModalOpen = true;
    } catch (error) {
      console.error('Error deleting event:', error);
      publicationResults = {
        success: [],
        failed: [{ relay: 'Unknown', error: error instanceof Error ? error.message : 'Unknown error' }]
      };
      publicationModalOpen = true;
    } finally {
      deleting = false;
    }
  }
</script>

<div class="event-menu-container">
  <button
    bind:this={menuButtonElement}
    class="menu-button"
    onclick={toggleMenu}
    aria-label="Event menu"
    aria-expanded={menuOpen}
  >
    <span class="menu-icon">⋯</span>
  </button>

  {#if menuOpen}
    <div 
      bind:this={menuDropdownElement}
      class="menu-dropdown"
      style="top: {menuPosition.top}px; right: {menuPosition.right}px;"
    >
      <button class="menu-item" onclick={copyUserId}>
        Copy user ID
        {#if copied === 'npub'}
          <span class="copied-indicator">✓</span>
        {/if}
      </button>
      <button class="menu-item" onclick={copyEventId}>
        Copy event ID
        {#if copied === 'nevent'}
          <span class="copied-indicator">✓</span>
        {/if}
      </button>
      <button class="menu-item" onclick={viewJson}>
        View JSON
      </button>
      {#if isLoggedIn}
        <button class="menu-item" onclick={viewRelatedEvents}>
          View your related events
        </button>
      {/if}
      <button class="menu-item" onclick={broadcastEvent} disabled={broadcasting}>
        {broadcasting ? 'Broadcasting...' : 'Broadcast event'}
      </button>
      <button class="menu-item" onclick={shareWithaitherboard}>
        Share with aitherboard
        {#if copied === 'share'}
          <span class="copied-indicator">✓</span>
        {/if}
      </button>

      {#if isLoggedIn && onReply}
        <div class="menu-divider"></div>
        <button class="menu-item" onclick={() => { onReply(); closeMenu(); }}>
          Reply
        </button>
      {/if}
      {#if isLoggedIn && showContentActions}
        <div class="menu-divider"></div>
        <button class="menu-item" onclick={pinNote} class:active={pinnedState}>
          Pin note
          {#if pinnedState}
            <span class="action-indicator">✓</span>
          {/if}
        </button>
        <button class="menu-item" onclick={bookmarkNote} class:active={bookmarkedState}>
          Bookmark note
          {#if bookmarkedState}
            <span class="action-indicator">✓</span>
          {/if}
        </button>
        <button class="menu-item" onclick={highlightNote} class:active={highlightedState}>
          Highlight note
          {#if highlightedState}
            <span class="action-indicator">✓</span>
          {/if}
        </button>
      {/if}
      
      {#if isLoggedIn && isOwnEvent}
        <div class="menu-divider"></div>
        <button class="menu-item menu-item-danger" onclick={confirmDelete} disabled={deleting}>
          {deleting ? 'Deleting...' : 'Delete event'}
        </button>
      {/if}
    </div>
  {/if}
</div>

<EventJsonModal bind:open={jsonModalOpen} event={event} />
<RelatedEventsModal bind:open={relatedEventsModalOpen} event={event} />
<PublicationStatusModal bind:open={publicationModalOpen} bind:results={publicationResults} />

{#if deleteConfirmOpen}
  <div 
    class="delete-confirm-overlay" 
    role="dialog"
    aria-modal="true"
    aria-labelledby="delete-dialog-title"
    onclick={(e) => {
      if (e.target === e.currentTarget) {
        deleteConfirmOpen = false;
      }
    }}
    onkeydown={(e) => {
      if (e.key === 'Escape') {
        deleteConfirmOpen = false;
      }
    }}
    tabindex="-1"
  >
    <div class="delete-confirm-dialog">
      <h3 id="delete-dialog-title">Delete Event?</h3>
      <p>Are you sure you want to delete this event? This action cannot be undone.</p>
      <div class="delete-confirm-buttons">
        <button class="btn-cancel" onclick={() => deleteConfirmOpen = false}>Cancel</button>
        <button class="btn-delete" onclick={deleteEvent} disabled={deleting}>
          {deleting ? 'Deleting...' : 'Delete'}
        </button>
      </div>
    </div>
  </div>
{/if}

<style>
  .event-menu-container {
    position: relative;
    display: inline-block;
    /* Ensure menu can overflow container */
    overflow: visible;
  }

  .menu-button {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    color: var(--fog-text-light, #9ca3af);
    font-size: 1.25rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: background-color 0.2s, color 0.2s;
    filter: grayscale(100%);
  }

  .menu-button:hover {
    background: var(--fog-highlight, #f3f4f6);
    color: var(--fog-text, #1f2937);
  }

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

  :global(.dark) .menu-button:hover {
    background: var(--fog-dark-highlight, #374151);
    color: var(--fog-dark-text, #f1f5f9);
  }

  .menu-icon {
    user-select: none;
    transform: rotate(90deg);
    display: inline-block;
    filter: grayscale(100%);
  }

  .menu-dropdown {
    position: fixed;
    background: var(--fog-post, #ffffff);
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    min-width: 200px;
    max-width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    z-index: 1000;
    overflow-y: auto;
    overflow-x: hidden;
  }

  :global(.dark) .menu-dropdown {
    background: var(--fog-dark-post, #1f2937);
    border-color: var(--fog-dark-border, #374151);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
  }

  .menu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    font-size: 0.875rem;
    color: var(--fog-text, #1f2937);
    transition: background-color 0.2s;
  }

  .menu-item:hover:not(:disabled) {
    background: var(--fog-highlight, #f3f4f6);
  }

  .menu-item:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .menu-item.active {
    background: var(--fog-highlight, #f3f4f6);
    font-weight: 500;
  }

  :global(.dark) .menu-item {
    color: var(--fog-dark-text, #f1f5f9);
  }

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

  :global(.dark) .menu-item.active {
    background: var(--fog-dark-highlight, #374151);
  }

  .action-indicator {
    color: var(--fog-accent, #64748b);
    font-weight: 600;
    margin-left: 0.5rem;
  }

  :global(.dark) .action-indicator {
    color: var(--fog-dark-accent, #94a3b8);
  }

  .menu-divider {
    height: 1px;
    background: var(--fog-border, #e5e7eb);
    margin: 0.25rem 0;
  }

  :global(.dark) .menu-divider {
    background: var(--fog-dark-border, #374151);
  }

  .copied-indicator {
    color: var(--fog-accent, #64748b);
    font-weight: 600;
    margin-left: 0.5rem;
  }

  :global(.dark) .copied-indicator {
    color: var(--fog-dark-accent, #94a3b8);
  }

  .menu-item-danger {
    color: var(--fog-danger, #dc2626);
  }

  :global(.dark) .menu-item-danger {
    color: var(--fog-dark-danger, #ef4444);
  }

  .menu-item-danger:hover:not(:disabled) {
    background: var(--fog-danger-light, #fee2e2);
  }

  :global(.dark) .menu-item-danger:hover:not(:disabled) {
    background: var(--fog-dark-danger-light, #7f1d1d);
  }

  .delete-confirm-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .delete-confirm-dialog {
    background: var(--fog-post, #ffffff);
    border-radius: 0.5rem;
    padding: 1.5rem;
    max-width: 400px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }

  :global(.dark) .delete-confirm-dialog {
    background: var(--fog-dark-post, #1f2937);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  }

  .delete-confirm-dialog h3 {
    margin: 0 0 0.5rem 0;
    color: var(--fog-text, #1f2937);
    font-size: 1.25rem;
  }

  :global(.dark) .delete-confirm-dialog h3 {
    color: var(--fog-dark-text, #f9fafb);
  }

  .delete-confirm-dialog p {
    margin: 0 0 1.5rem 0;
    color: var(--fog-text-light, #6b7280);
  }

  :global(.dark) .delete-confirm-dialog p {
    color: var(--fog-dark-text-light, #9ca3af);
  }

  .delete-confirm-buttons {
    display: flex;
    gap: 0.75rem;
    justify-content: flex-end;
  }

  .btn-cancel,
  .btn-delete {
    padding: 0.5rem 1rem;
    border-radius: 0.25rem;
    border: none;
    cursor: pointer;
    font-size: 0.875rem;
    transition: all 0.2s;
  }

  .btn-cancel {
    background: var(--fog-highlight, #f3f4f6);
    color: var(--fog-text, #1f2937);
  }

  :global(.dark) .btn-cancel {
    background: var(--fog-dark-highlight, #374151);
    color: var(--fog-dark-text, #f9fafb);
  }

  .btn-cancel:hover {
    background: var(--fog-border, #e5e7eb);
  }

  :global(.dark) .btn-cancel:hover {
    background: var(--fog-dark-border, #475569);
  }

  .btn-delete {
    background: var(--fog-danger, #dc2626);
    color: white;
  }

  :global(.dark) .btn-delete {
    background: var(--fog-dark-danger, #ef4444);
  }

  .btn-delete:hover:not(:disabled) {
    background: var(--fog-danger-dark, #b91c1c);
  }

  :global(.dark) .btn-delete:hover:not(:disabled) {
    background: var(--fog-dark-danger-dark, #dc2626);
  }

  .btn-delete:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
</style>
