<script lang="ts">
  import { nip19 } from 'nostr-tools';
  import { goto } from '$app/navigation';
  import { sessionManager } from '../../services/auth/session-manager.js';
  import { nostrClient } from '../../services/nostr/nostr-client.js';
  import { relayManager } from '../../services/nostr/relay-manager.js';
  import { getProfile } from '../../services/cache/profile-cache.js';
  import { KIND } from '../../types/kind-lookup.js';
  import type { NostrEvent } from '../../types/nostr.js';
  import { toggleMute, toggleFollow, isMuted, isFollowed } from '../../services/user-actions.js';
  import Icon from '../ui/Icon.svelte';

  interface Props {
    pubkey: string;
    onOpenBookmarks?: () => void;
  }

  let { pubkey, onOpenBookmarks }: Props = $props();

  let menuOpen = $state(false);
  let menuButtonElement: HTMLButtonElement | null = $state(null);
  let menuDropdownElement: HTMLDivElement | null = $state(null);
  let menuPosition = $state({ top: 0, right: 0 });
  let copied = $state<string | null>(null);
  let profileEvent = $state<NostrEvent | null>(null);
  let muting = $state(false);
  let following = $state(false);

  let isLoggedIn = $derived(sessionManager.isLoggedIn());
  let currentUserPubkey = $derived(sessionManager.getCurrentPubkey());
  let isOwnProfile = $derived(isLoggedIn && currentUserPubkey === pubkey);
  let muted = $state(false);
  let followed = $state(false);
  
  // Update mute and follow state
  $effect(() => {
    if (pubkey) {
      isMuted(pubkey).then(m => {
        muted = m;
      });
      isFollowed(pubkey).then(f => {
        followed = f;
      });
    }
  });

  // Load kind 0 event for this profile
  $effect(() => {
    if (pubkey) {
      loadProfileEvent();
    }
  });

  async function loadProfileEvent() {
    try {
      // Try cache first
      const cached = await getProfile(pubkey);
      if (cached) {
        profileEvent = cached.event;
        return;
      }

      // Fetch from relays if not in cache
      const relays = relayManager.getProfileReadRelays();
      const events = await nostrClient.fetchEvents(
        [{ kinds: [KIND.METADATA], authors: [pubkey], limit: 1 }],
        relays,
        { useCache: true, cacheResults: true }
      );

      if (events.length > 0) {
        profileEvent = events[0];
      }
    } catch (error) {
      console.error('Error loading profile event:', error);
    }
  }

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

  function openMenu() {
    menuOpen = true;
    requestAnimationFrame(() => {
      positionMenu();
    });
  }

  // Reposition menu on window resize
  $effect(() => {
    if (!menuOpen) return;
    
    function handleResize() {
      positionMenu();
    }
    
    window.addEventListener('resize', handleResize);
    window.addEventListener('scroll', handleResize, true);
    
    return () => {
      window.removeEventListener('resize', handleResize);
      window.removeEventListener('scroll', handleResize, true);
    };
  });

  function closeMenu() {
    menuOpen = false;
  }

  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
    
    // Initial position: below button, aligned to right edge
    let top = buttonRect.bottom + 4;
    let right = viewportWidth - buttonRect.right;

    menuPosition = { top, right };

    requestAnimationFrame(() => {
      if (!menuDropdownElement) return;
      const dropdownRect = menuDropdownElement.getBoundingClientRect();
      const dropdownWidth = dropdownRect.width;
      const dropdownHeight = dropdownRect.height;
      
      // Calculate left position from right
      const left = viewportWidth - right - dropdownWidth;
      
      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 };
    });
  }

  // Close menu when clicking outside
  $effect(() => {
    if (!menuOpen) return;

    function handleClickOutside(event: MouseEvent) {
      if (
        menuButtonElement &&
        menuDropdownElement &&
        !menuButtonElement.contains(event.target as Node) &&
        !menuDropdownElement.contains(event.target as Node)
      ) {
        closeMenu();
      }
    }

    function handleEscape(event: KeyboardEvent) {
      if (event.key === 'Escape') {
        closeMenu();
      }
    }

    document.addEventListener('mousedown', handleClickOutside);
    document.addEventListener('keydown', handleEscape);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
      document.removeEventListener('keydown', handleEscape);
    };
  });

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

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

  function shareWithAitherboard() {
    const url = `${window.location.origin}/profile/${pubkey}`;
    navigator.clipboard.writeText(url).then(() => {
      copied = 'share';
      setTimeout(() => {
        copied = null;
      }, 2000);
    }).catch(error => {
      console.error('Failed to copy share URL:', error);
    });
    closeMenu();
  }

  function seeBookmarks() {
    if (onOpenBookmarks) {
      onOpenBookmarks();
    }
    closeMenu();
  }

  async function handleMute() {
    if (muting || isOwnProfile) return;
    muting = true;
    try {
      await toggleMute(pubkey);
      // Update state
      const newMuted = await isMuted(pubkey);
      muted = newMuted;
    } catch (error) {
      console.error('Failed to toggle mute:', error);
    } finally {
      muting = false;
      closeMenu();
    }
  }

  async function handleFollow() {
    if (following || isOwnProfile) return;
    following = true;
    try {
      await toggleFollow(pubkey);
      // Update state
      const newFollowed = await isFollowed(pubkey);
      followed = newFollowed;
    } catch (error) {
      console.error('Failed to toggle follow:', error);
    } finally {
      following = false;
      closeMenu();
    }
  }
</script>

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

  {#if menuOpen}
    <div
      bind:this={menuDropdownElement}
      class="menu-dropdown"
      style="top: {menuPosition.top}px; right: {menuPosition.right}px;"
      role="menu"
    >
      <button class="menu-item" onclick={copyUserId} role="menuitem">
        <span class="menu-item-icon">📋</span>
        <span class="menu-item-text">Copy user ID (npub)</span>
        {#if copied === 'userId'}
          <span class="menu-item-check">✓</span>
        {/if}
      </button>
      
      <button class="menu-item" onclick={copyEventId} role="menuitem" disabled={!profileEvent}>
        <span class="menu-item-icon">📋</span>
        <span class="menu-item-text">Copy event ID (nevent)</span>
        {#if copied === 'eventId'}
          <span class="menu-item-check">✓</span>
        {/if}
      </button>
      
      <div class="menu-divider"></div>
      
      <button class="menu-item" onclick={shareWithAitherboard} role="menuitem">
        <span class="menu-item-icon">🔗</span>
        <span class="menu-item-text">Share with aitherboard</span>
        {#if copied === 'share'}
          <span class="menu-item-check">✓</span>
        {/if}
      </button>
      
      {#if isLoggedIn && !isOwnProfile}
        <div class="menu-divider"></div>
        
        <button 
          class="menu-item" 
          onclick={handleMute} 
          role="menuitem"
          disabled={muting}
        >
          <span class="menu-item-icon">{muted ? '🔇' : '🔊'}</span>
          <span class="menu-item-text">{muted ? 'Unmute this user' : 'Mute this user'}</span>
          {#if muted}
            <span class="menu-item-check">✓</span>
          {/if}
        </button>
        
        <button 
          class="menu-item" 
          onclick={handleFollow} 
          role="menuitem"
          disabled={following}
        >
          <span class="menu-item-icon">
            {#if followed}
              <Icon name="user" size={16} />
            {:else}
              <Icon name="plus" size={16} />
            {/if}
          </span>
          <span class="menu-item-text">{followed ? 'Unfollow this user' : 'Follow this user'}</span>
          {#if followed}
            <span class="menu-item-check">✓</span>
          {/if}
        </button>
      {/if}
      
    </div>
  {/if}
</div>

<style>
  .profile-menu-container {
    position: relative;
    display: inline-block;
  }

  .menu-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.25rem 0.5rem;
    background: var(--fog-post, #ffffff);
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.25rem;
    cursor: pointer;
    transition: all 0.2s;
    font-size: 0.875rem;
    min-width: 2rem;
    min-height: 2rem;
    filter: grayscale(100%);
  }

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

  .menu-button:hover {
    background: var(--fog-highlight, #f3f4f6);
    border-color: var(--fog-accent, #64748b);
  }

  :global(.dark) .menu-button:hover {
    background: var(--fog-dark-highlight, #475569);
    border-color: var(--fog-dark-accent, #94a3b8);
  }

  .menu-icon {
    font-size: 1.25rem;
    line-height: 1;
    color: var(--fog-text, #1f2937);
    filter: grayscale(100%);
  }

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

  .menu-dropdown {
    position: fixed;
    z-index: 1000;
    background: var(--fog-post, #ffffff);
    border: 1px solid var(--fog-border, #e5e7eb);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    min-width: 180px;
    max-width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    padding: 0.25rem;
    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 12px rgba(0, 0, 0, 0.3);
  }

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

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

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

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

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

  .menu-item-icon {
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
    filter: grayscale(100%);
  }

  .menu-item-text {
    flex: 1;
  }

  .menu-item-check {
    color: var(--fog-accent, #64748b);
    font-weight: 600;
    flex-shrink: 0;
  }

  :global(.dark) .menu-item-check {
    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);
  }
</style>
