/**
 * NOSTR_LOGIN_LITE - Authentication Library
 *
 * ⚠️  WARNING: THIS FILE IS AUTO-GENERATED - DO NOT EDIT MANUALLY!
 * ⚠️  To make changes, edit lite/build.js and run: cd lite && node build.js
 * ⚠️  Any manual edits to this file will be OVERWRITTEN when build.js runs!
 *
 * Two-file architecture:
 * 1. Load nostr.bundle.js (official nostr-tools bundle)
 * 2. Load nostr-lite.js (this file - NOSTR_LOGIN_LITE library with CSS-only themes)
 * Generated on: 2025-09-20T19:25:01.143Z
 */

// Verify dependencies are loaded
if (typeof window !== 'undefined') {
  if (!window.NostrTools) {
    console.error('NOSTR_LOGIN_LITE: nostr.bundle.js must be loaded first');
    throw new Error('Missing dependency: nostr.bundle.js');
  }
  
  console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓');
  console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools));
  console.log('NOSTR_LOGIN_LITE: NIP-06 available:', !!window.NostrTools.nip06);
  console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46);
}

// ======================================
// NOSTR_LOGIN_LITE Components
// ======================================

// ======================================
// CSS-Only Theme System
// ======================================

const THEME_CSS = {
  'default': `/**
 * NOSTR_LOGIN_LITE - Default Monospace Theme
 * Black/white/red color scheme with monospace typography
 * Simplified 14-variable system (6 core + 8 floating tab)
 */

:root {
  /* Core Variables (6) */
  --nl-primary-color: #000000;
  --nl-secondary-color: #ffffff;
  --nl-accent-color: #ff0000;
  --nl-muted-color: #CCCCCC;
  --nl-font-family: "Courier New", Courier, monospace;
  --nl-border-radius: 15px;
  --nl-border-width: 3px;
  
  /* Floating Tab Variables (8) */
  --nl-tab-bg-logged-out: #ffffff;
  --nl-tab-bg-logged-in: #ffffff;
  --nl-tab-bg-opacity-logged-out: 0.9;
  --nl-tab-bg-opacity-logged-in: 0.2;
  --nl-tab-color-logged-out: #000000;
  --nl-tab-color-logged-in: #ffffff;
  --nl-tab-border-logged-out: #000000;
  --nl-tab-border-logged-in: #ff0000;
  --nl-tab-border-opacity-logged-out: 1.0;
  --nl-tab-border-opacity-logged-in: 0.1;
}

/* Base component styles using simplified variables */
.nl-component {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

.nl-button {
  background: var(--nl-secondary-color);
  color: var(--nl-primary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
  font-family: var(--nl-font-family);
  cursor: pointer;
  transition: all 0.2s ease;
}

.nl-button:hover {
  border-color: var(--nl-accent-color);
}

.nl-button:active {
  background: var(--nl-accent-color);
  color: var(--nl-secondary-color);
}

.nl-input {
  background: var(--nl-secondary-color);
  color: var(--nl-primary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
  font-family: var(--nl-font-family);
  box-sizing: border-box;
}

.nl-input:focus {
  border-color: var(--nl-accent-color);
  outline: none;
}

.nl-container {
  background: var(--nl-secondary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
}

.nl-title, .nl-heading {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
  margin: 0;
}

.nl-text {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

.nl-text--muted {
  color: var(--nl-muted-color);
}

.nl-icon {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

/* Floating tab styles */
.nl-floating-tab {
  font-family: var(--nl-font-family);
  border-radius: var(--nl-border-radius);
  border: var(--nl-border-width) solid;
  transition: all 0.2s ease;
}

.nl-floating-tab--logged-out {
  background: rgba(255, 255, 255, var(--nl-tab-bg-opacity-logged-out));
  color: var(--nl-tab-color-logged-out);
  border-color: rgba(0, 0, 0, var(--nl-tab-border-opacity-logged-out));
}

.nl-floating-tab--logged-in {
  background: rgba(0, 0, 0, var(--nl-tab-bg-opacity-logged-in));
  color: var(--nl-tab-color-logged-in);
  border-color: rgba(255, 0, 0, var(--nl-tab-border-opacity-logged-in));
}

.nl-transition {
  transition: all 0.2s ease;
}`,
  'dark': `/**
 * NOSTR_LOGIN_LITE - Dark Monospace Theme
 */

:root {
  /* Core Variables (6) */
  --nl-primary-color: #white;
  --nl-secondary-color: #black;
  --nl-accent-color: #ff0000;
  --nl-muted-color: #666666;
  --nl-font-family: "Courier New", Courier, monospace;
  --nl-border-radius: 15px;
  --nl-border-width: 3px;
  
  /* Floating Tab Variables (8) */
  --nl-tab-bg-logged-out: #ffffff;
  --nl-tab-bg-logged-in: #000000;
  --nl-tab-bg-opacity-logged-out: 0.9;
  --nl-tab-bg-opacity-logged-in: 0.8;
  --nl-tab-color-logged-out: #000000;
  --nl-tab-color-logged-in: #ffffff;
  --nl-tab-border-logged-out: #000000;
  --nl-tab-border-logged-in: #ff0000;
  --nl-tab-border-opacity-logged-out: 1.0;
  --nl-tab-border-opacity-logged-in: 0.9;
}

/* Base component styles using simplified variables */
.nl-component {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

.nl-button {
  background: var(--nl-secondary-color);
  color: var(--nl-primary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
  font-family: var(--nl-font-family);
  cursor: pointer;
  transition: all 0.2s ease;
}

.nl-button:hover {
  border-color: var(--nl-accent-color);
}

.nl-button:active {
  background: var(--nl-accent-color);
  color: var(--nl-secondary-color);
}

.nl-input {
  background: var(--nl-secondary-color);
  color: var(--nl-primary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
  font-family: var(--nl-font-family);
  box-sizing: border-box;
}

.nl-input:focus {
  border-color: var(--nl-accent-color);
  outline: none;
}

.nl-container {
  background: var(--nl-secondary-color);
  border: var(--nl-border-width) solid var(--nl-primary-color);
  border-radius: var(--nl-border-radius);
}

.nl-title, .nl-heading {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
  margin: 0;
}

.nl-text {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

.nl-text--muted {
  color: var(--nl-muted-color);
}

.nl-icon {
  font-family: var(--nl-font-family);
  color: var(--nl-primary-color);
}

/* Floating tab styles */
.nl-floating-tab {
  font-family: var(--nl-font-family);
  border-radius: var(--nl-border-radius);
  border: var(--nl-border-width) solid;
  transition: all 0.2s ease;
}

.nl-floating-tab--logged-out {
  background: rgba(255, 255, 255, var(--nl-tab-bg-opacity-logged-out));
  color: var(--nl-tab-color-logged-out);
  border-color: rgba(0, 0, 0, var(--nl-tab-border-opacity-logged-out));
}

.nl-floating-tab--logged-in {
  background: rgba(0, 0, 0, var(--nl-tab-bg-opacity-logged-in));
  color: var(--nl-tab-color-logged-in);
  border-color: rgba(255, 0, 0, var(--nl-tab-border-opacity-logged-in));
}

.nl-transition {
  transition: all 0.2s ease;
}`
};

// Theme management functions
function injectThemeCSS(themeName = 'default') {
  if (typeof document !== 'undefined') {
    // Remove existing theme CSS
    const existingStyle = document.getElementById('nl-theme-css');
    if (existingStyle) {
      existingStyle.remove();
    }
    
    // Inject selected theme CSS
    const themeCss = THEME_CSS[themeName] || THEME_CSS['default'];
    const style = document.createElement('style');
    style.id = 'nl-theme-css';
    style.textContent = themeCss;
    document.head.appendChild(style);
    console.log(`NOSTR_LOGIN_LITE: ${themeName} theme CSS injected`);
  }
}

// Auto-inject default theme when DOM is ready
if (typeof document !== 'undefined') {
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => injectThemeCSS('default'));
  } else {
    injectThemeCSS('default');
  }
}

// ======================================
// Modal UI Component
// ======================================


class Modal {
  constructor(options = {}) {
    this.options = options;
    this.container = null;
    this.isVisible = false;
    this.currentScreen = null;
    this.isEmbedded = !!options.embedded;
    this.embeddedContainer = options.embedded;

    // Initialize modal container and styles
    this._initModal();
  }

  _initModal() {
    // Create modal container
    this.container = document.createElement('div');
    this.container.id = this.isEmbedded ? 'nl-modal-embedded' : 'nl-modal';
    
    if (this.isEmbedded) {
      // Embedded mode: inline positioning, no overlay
      this.container.style.cssText = `
        position: relative;
        display: none;
        font-family: var(--nl-font-family, 'Courier New', monospace);
        width: 100%;
      `;
    } else {
      // Modal mode: fixed overlay
      this.container.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.75);
        display: none;
        z-index: 10000;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;
    }

    // Create modal content
    const modalContent = document.createElement('div');
    if (this.isEmbedded) {
      // Embedded content: no centering margin, full width
      modalContent.style.cssText = `
        position: relative;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        width: 100%;
        border-radius: var(--nl-border-radius, 15px);
        border: var(--nl-border-width) solid var(--nl-primary-color);
        overflow: hidden;
      `;
    } else {
      // Modal content: centered with margin, no fixed height
      modalContent.style.cssText = `
        position: relative;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        width: 90%;
        max-width: 400px;
        margin: 50px auto;
        border-radius: var(--nl-border-radius, 15px);
        border: var(--nl-border-width) solid var(--nl-primary-color);
        overflow: hidden;
      `;
    }

    // Header
    const modalHeader = document.createElement('div');
    modalHeader.style.cssText = `
      padding: 20px 24px 0 24px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: transparent;
      border-bottom: none;
    `;

    const modalTitle = document.createElement('h2');
    modalTitle.textContent = 'Nostr Login';
    modalTitle.style.cssText = `
      margin: 0;
      font-size: 24px;
      font-weight: 600;
      color: var(--nl-primary-color);
      font-family: var(--nl-font-family, 'Courier New', monospace);
    `;

    modalHeader.appendChild(modalTitle);
    
    // Only add close button for non-embedded modals
    // Embedded modals shouldn't have a close button because there's no way to reopen them
    if (!this.isEmbedded) {
      const closeButton = document.createElement('button');
      closeButton.innerHTML = '×';
      closeButton.onclick = () => this.close();
      closeButton.style.cssText = `
        background: var(--nl-secondary-color);
        border: var(--nl-border-width) solid var(--nl-primary-color);
        border-radius: 4px;
        font-size: 28px;
        color: var(--nl-primary-color);
        cursor: pointer;
        padding: 0;
        width: 32px;
        height: 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;
      closeButton.onmouseover = () => {
        closeButton.style.borderColor = 'var(--nl-accent-color)';
        closeButton.style.background = 'var(--nl-secondary-color)';
      };
      closeButton.onmouseout = () => {
        closeButton.style.borderColor = 'var(--nl-primary-color)';
        closeButton.style.background = 'var(--nl-secondary-color)';
      };
      
      modalHeader.appendChild(closeButton);
    }

    // Body
    this.modalBody = document.createElement('div');
    this.modalBody.style.cssText = `
      padding: 24px;
      background: transparent;
      font-family: var(--nl-font-family, 'Courier New', monospace);
    `;

    modalContent.appendChild(modalHeader);
    modalContent.appendChild(this.modalBody);
    this.container.appendChild(modalContent);

    // Add to appropriate parent
    if (this.isEmbedded && this.embeddedContainer) {
      // Append to specified container for embedding
      if (typeof this.embeddedContainer === 'string') {
        const targetElement = document.querySelector(this.embeddedContainer);
        if (targetElement) {
          targetElement.appendChild(this.container);
        } else {
          console.error('NOSTR_LOGIN_LITE: Embedded container not found:', this.embeddedContainer);
          document.body.appendChild(this.container);
        }
      } else if (this.embeddedContainer instanceof HTMLElement) {
        this.embeddedContainer.appendChild(this.container);
      } else {
        console.error('NOSTR_LOGIN_LITE: Invalid embedded container');
        document.body.appendChild(this.container);
      }
    } else {
      // Add to body for modal mode
      document.body.appendChild(this.container);
    }

    // Click outside to close (only for modal mode)
    if (!this.isEmbedded) {
      this.container.onclick = (e) => {
        if (e.target === this.container) {
          this.close();
        }
      };
    }

    // Update theme
    this.updateTheme();
  }

  updateTheme() {
    // The theme will automatically update through CSS custom properties
    // No manual styling needed - the CSS variables handle everything
  }

  open(opts = {}) {
    this.currentScreen = opts.startScreen;
    this.isVisible = true;
    this.container.style.display = 'block';

    // Render login options
    this._renderLoginOptions();
  }

  close() {
    this.isVisible = false;
    this.container.style.display = 'none';
    this.modalBody.innerHTML = '';
  }

  _renderLoginOptions() {
    this.modalBody.innerHTML = '';

    const options = [];

    // Extension option
    if (this.options?.methods?.extension !== false) {
      options.push({
        type: 'extension',
        title: 'Browser Extension',
        description: 'Use your browser extension',
        icon: '🔌'
      });
    }

    // Local key option
    if (this.options?.methods?.local !== false) {
      options.push({
        type: 'local',
        title: 'Local Key',
        description: 'Create or import your own key',
        icon: '🔑'
      });
    }

    // Seed Phrase option - only show if explicitly enabled
    if (this.options?.methods?.seedphrase === true) {
      options.push({
        type: 'seedphrase',
        title: 'Seed Phrase',
        description: 'Import from mnemonic seed phrase',
        icon: '🌱'
      });
    }

    // Nostr Connect option (check both 'connect' and 'remote' for compatibility)
    if (this.options?.methods?.connect !== false && this.options?.methods?.remote !== false) {
      options.push({
        type: 'connect',
        title: 'Nostr Connect',
        description: 'Connect with external signer',
        icon: '🌐'
      });
    }

    // Read-only option
    if (this.options?.methods?.readonly !== false) {
      options.push({
        type: 'readonly',
        title: 'Read Only',
        description: 'Browse without signing',
        icon: '👁️'
      });
    }

    // OTP/DM option
    if (this.options?.methods?.otp !== false) {
      options.push({
        type: 'otp',
        title: 'DM/OTP',
        description: 'Receive OTP via DM',
        icon: '📱'
      });
    }

    // Render each option
    options.forEach(option => {
      const button = document.createElement('button');
      button.onclick = () => this._handleOptionClick(option.type);
      button.style.cssText = `
        display: flex;
        align-items: center;
        width: 100%;
        padding: 16px;
        margin-bottom: 12px;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        border: var(--nl-border-width) solid var(--nl-primary-color);
        border-radius: var(--nl-border-radius);
        cursor: pointer;
        transition: all 0.2s;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;
      button.onmouseover = () => {
        button.style.borderColor = 'var(--nl-accent-color)';
        button.style.background = 'var(--nl-secondary-color)';
      };
      button.onmouseout = () => {
        button.style.borderColor = 'var(--nl-primary-color)';
        button.style.background = 'var(--nl-secondary-color)';
      };

      const iconDiv = document.createElement('div');
      // Remove the icon entirely - no emojis or text-based icons
      iconDiv.textContent = '';
      iconDiv.style.cssText = `
        font-size: 16px;
        font-weight: bold;
        margin-right: 16px;
        width: 0px;
        text-align: center;
        color: var(--nl-primary-color);
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;

      const contentDiv = document.createElement('div');
      contentDiv.style.cssText = 'flex: 1; text-align: left;';

      const titleDiv = document.createElement('div');
      titleDiv.textContent = option.title;
      titleDiv.style.cssText = `
        font-weight: 600;
        margin-bottom: 4px;
        color: var(--nl-primary-color);
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;

      const descDiv = document.createElement('div');
      descDiv.textContent = option.description;
      descDiv.style.cssText = `
        font-size: 14px;
        color: #666666;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;

      contentDiv.appendChild(titleDiv);
      contentDiv.appendChild(descDiv);

      button.appendChild(iconDiv);
      button.appendChild(contentDiv);
      this.modalBody.appendChild(button);
    });
  }

  _handleOptionClick(type) {
    console.log('Selected login type:', type);

    // Handle different login types
    switch (type) {
      case 'extension':
        this._handleExtension();
        break;
      case 'local':
        this._showLocalKeyScreen();
        break;
      case 'seedphrase':
        this._showSeedPhraseScreen();
        break;
      case 'connect':
        this._showConnectScreen();
        break;
      case 'readonly':
        this._handleReadonly();
        break;
      case 'otp':
        this._showOtpScreen();
        break;
    }
  }

  _handleExtension() {
    // SIMPLIFIED ARCHITECTURE: Check for single extension at window.nostr or preserved extension
    let extension = null;
    
    // Check if NostrLite instance has a preserved extension (real extension detected at init)
    if (window.NOSTR_LOGIN_LITE?._instance?.preservedExtension) {
      extension = window.NOSTR_LOGIN_LITE._instance.preservedExtension;
      console.log('Modal: Using preserved extension:', extension.constructor?.name);
    }
    // Otherwise check current window.nostr
    else if (window.nostr && this._isRealExtension(window.nostr)) {
      extension = window.nostr;
      console.log('Modal: Using current window.nostr extension:', extension.constructor?.name);
    }
    
    if (!extension) {
      console.log('Modal: No extension detected yet, waiting for deferred detection...');
      
      // DEFERRED EXTENSION CHECK: Extensions like nos2x might load after our library
      let attempts = 0;
      const maxAttempts = 10; // Try for 2 seconds
      const checkForExtension = () => {
        attempts++;
        
        // Check again for preserved extension (might be set by deferred detection)
        if (window.NOSTR_LOGIN_LITE?._instance?.preservedExtension) {
          extension = window.NOSTR_LOGIN_LITE._instance.preservedExtension;
          console.log('Modal: Found preserved extension after waiting:', extension.constructor?.name);
          this._tryExtensionLogin(extension);
          return;
        }
        
        // Check current window.nostr again
        if (window.nostr && this._isRealExtension(window.nostr)) {
          extension = window.nostr;
          console.log('Modal: Found extension at window.nostr after waiting:', extension.constructor?.name);
          this._tryExtensionLogin(extension);
          return;
        }
        
        // Keep trying or give up
        if (attempts < maxAttempts) {
          setTimeout(checkForExtension, 200);
        } else {
          console.log('Modal: No browser extension found after waiting 2 seconds');
          this._showExtensionRequired();
        }
      };
      
      // Start checking after a brief delay
      setTimeout(checkForExtension, 200);
      return;
    }
    
    // Use the single detected extension directly - no choice UI
    console.log('Modal: Single extension mode - using extension directly');
    this._tryExtensionLogin(extension);
  }

  _detectAllExtensions() {
    const extensions = [];
    const seenExtensions = new Set(); // Track extensions by object reference to avoid duplicates
    
    // Extension locations to check (in priority order)
    const locations = [
      { path: 'window.navigator?.nostr', name: 'navigator.nostr', displayName: 'Standard Extension (navigator.nostr)', icon: '🌐', getter: () => window.navigator?.nostr },
      { path: 'window.webln?.nostr', name: 'webln.nostr', displayName: 'Alby WebLN Extension', icon: '⚡', getter: () => window.webln?.nostr },
      { path: 'window.alby?.nostr', name: 'alby.nostr', displayName: 'Alby Extension (Direct)', icon: '🐝', getter: () => window.alby?.nostr },
      { path: 'window.nos2x', name: 'nos2x', displayName: 'nos2x Extension', icon: '🔌', getter: () => window.nos2x },
      { path: 'window.flamingo?.nostr', name: 'flamingo.nostr', displayName: 'Flamingo Extension', icon: '🦩', getter: () => window.flamingo?.nostr },
      { path: 'window.mutiny?.nostr', name: 'mutiny.nostr', displayName: 'Mutiny Extension', icon: '⚔️', getter: () => window.mutiny?.nostr },
      { path: 'window.nostrich?.nostr', name: 'nostrich.nostr', displayName: 'Nostrich Extension', icon: '🐦', getter: () => window.nostrich?.nostr },
      { path: 'window.getAlby?.nostr', name: 'getAlby.nostr', displayName: 'getAlby Extension', icon: '🔧', getter: () => window.getAlby?.nostr }
    ];

    // Check each location
    for (const location of locations) {
      try {
        const obj = location.getter();
        
        console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name);
        
        if (obj && this._isRealExtension(obj) && !seenExtensions.has(obj)) {
          extensions.push({
            name: location.name,
            displayName: location.displayName,
            icon: location.icon,
            extension: obj
          });
          seenExtensions.add(obj);
          console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`);
        } else if (obj) {
          console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`);
        }
      } catch (e) {
        // Location doesn't exist or can't be accessed
        console.log(`Modal: ${location.name} not accessible:`, e.message);
      }
    }
    
    // Also check window.nostr but be extra careful to avoid our library
    console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
    
    if (window.nostr) {
      // Check if window.nostr is our WindowNostr facade with a preserved extension
      if (window.nostr.constructor?.name === 'WindowNostr' && window.nostr.existingNostr) {
        console.log('Modal: Found WindowNostr facade, checking existingNostr for preserved extension');
        const preservedExtension = window.nostr.existingNostr;
        console.log('Modal: Preserved extension:', !!preservedExtension, preservedExtension?.constructor?.name);
        
        if (preservedExtension && this._isRealExtension(preservedExtension) && !seenExtensions.has(preservedExtension)) {
          extensions.push({
            name: 'window.nostr.existingNostr',
            displayName: 'Extension (preserved by WindowNostr)',
            icon: '🔑',
            extension: preservedExtension
          });
          seenExtensions.add(preservedExtension);
          console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
        }
      }
      // Check if window.nostr is directly a real extension (not our facade)
      else if (this._isRealExtension(window.nostr) && !seenExtensions.has(window.nostr)) {
        extensions.push({
          name: 'window.nostr',
          displayName: 'Extension (window.nostr)',
          icon: '🔑',
          extension: window.nostr
        });
        seenExtensions.add(window.nostr);
        console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`);
      } else {
        console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - not a real extension`);
      }
    }
    
    return extensions;
  }

  _isRealExtension(obj) {
    console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj);
    console.log(`Modal: Object type: ${typeof obj}`);
    console.log(`Modal: Object truthy: ${!!obj}`);
    
    if (!obj || typeof obj !== 'object') {
      console.log(`Modal: REJECT - Not an object`);
      return false;
    }
    
    console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`);
    console.log(`Modal: signEvent type: ${typeof obj.signEvent}`);
    
    // Must have required Nostr methods
    if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') {
      console.log(`Modal: REJECT - Missing required methods`);
      return false;
    }

    // Exclude NostrTools library object
    if (obj === window.NostrTools) {
      console.log(`Modal: REJECT - Is NostrTools object`);
      return false;
    }

    // Use the EXACT SAME logic as the comprehensive test (lines 804-809)
    // This is the key fix - match the comprehensive test's successful detection logic
    const constructorName = obj.constructor?.name;
    const objectKeys = Object.keys(obj);
    
    console.log(`Modal: Constructor name: "${constructorName}"`);
    console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`);
    
    // COMPREHENSIVE TEST LOGIC - Accept anything with required methods that's not our specific library classes
    const isRealExtension = (
      typeof obj.getPublicKey === 'function' &&
      typeof obj.signEvent === 'function' &&
      constructorName !== 'WindowNostr' && // Our library class
      constructorName !== 'NostrLite' // Our main class
    );
    
    console.log(`Modal: Using comprehensive test logic:`);
    console.log(`  Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`);
    console.log(`  Has signEvent: ${typeof obj.signEvent === 'function'}`);
    console.log(`  Not WindowNostr: ${constructorName !== 'WindowNostr'}`);
    console.log(`  Not NostrLite: ${constructorName !== 'NostrLite'}`);
    console.log(`  Constructor: "${constructorName}"`);
    
    // Additional debugging for comparison
    const extensionPropChecks = {
      _isEnabled: !!obj._isEnabled,
      enabled: !!obj.enabled,
      kind: !!obj.kind,
      _eventEmitter: !!obj._eventEmitter,
      _scope: !!obj._scope,
      _requests: !!obj._requests,
      _pubkey: !!obj._pubkey,
      name: !!obj.name,
      version: !!obj.version,
      description: !!obj.description
    };
    
    console.log(`Modal: Extension property analysis:`, extensionPropChecks);
    
    const hasExtensionProps = !!(
      obj._isEnabled || obj.enabled || obj.kind ||
      obj._eventEmitter || obj._scope || obj._requests || obj._pubkey ||
      obj.name || obj.version || obj.description
    );
    
    const underscoreKeys = objectKeys.filter(key => key.startsWith('_'));
    const hexToUint8Keys = objectKeys.filter(key => key.startsWith('_hex'));
    console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`);
    console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`);
    
    console.log(`Modal: Additional analysis:`);
    console.log(`  hasExtensionProps: ${hasExtensionProps}`);
    console.log(`  hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`);
    
    console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
    console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
    
    return isRealExtension;
  }

  _showExtensionChoice(extensions) {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Choose Browser Extension';
    title.style.cssText = `
      margin: 0 0 16px 0;
      font-size: 18px;
      font-weight: 600;
      color: var(--nl-primary-color);
      font-family: var(--nl-font-family, 'Courier New', monospace);
    `;

    const description = document.createElement('p');
    description.textContent = `Found ${extensions.length} Nostr extensions. Choose which one to use:`;
    description.style.cssText = `
      margin-bottom: 20px;
      color: #666666;
      font-size: 14px;
      font-family: var(--nl-font-family, 'Courier New', monospace);
    `;

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(description);

    // Create button for each extension
    extensions.forEach((ext, index) => {
      const button = document.createElement('button');
      button.onclick = () => this._tryExtensionLogin(ext.extension);
      button.style.cssText = `
        display: flex;
        align-items: center;
        width: 100%;
        padding: 16px;
        margin-bottom: 12px;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        border: var(--nl-border-width) solid var(--nl-primary-color);
        border-radius: var(--nl-border-radius);
        cursor: pointer;
        transition: all 0.2s;
        text-align: left;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;
      
      button.onmouseover = () => {
        button.style.borderColor = 'var(--nl-accent-color)';
        button.style.background = 'var(--nl-secondary-color)';
      };
      button.onmouseout = () => {
        button.style.borderColor = 'var(--nl-primary-color)';
        button.style.background = 'var(--nl-secondary-color)';
      };

      const iconDiv = document.createElement('div');
      iconDiv.textContent = ext.icon;
      iconDiv.style.cssText = `
        font-size: 24px;
        margin-right: 16px;
        width: 24px;
        text-align: center;
      `;

      const contentDiv = document.createElement('div');
      contentDiv.style.cssText = 'flex: 1;';

      const nameDiv = document.createElement('div');
      nameDiv.textContent = ext.displayName;
      nameDiv.style.cssText = `
        font-weight: 600;
        margin-bottom: 4px;
        color: var(--nl-primary-color);
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;

      const pathDiv = document.createElement('div');
      pathDiv.textContent = ext.name;
      pathDiv.style.cssText = `
        font-size: 12px;
        color: #666666;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;

      contentDiv.appendChild(nameDiv);
      contentDiv.appendChild(pathDiv);
      
      button.appendChild(iconDiv);
      button.appendChild(contentDiv);
      this.modalBody.appendChild(button);
    });

    // Add back button
    const backButton = document.createElement('button');
    backButton.textContent = 'Back to Login Options';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 20px;';
    
    this.modalBody.appendChild(backButton);
  }

  async _tryExtensionLogin(extensionObj) {
    try {
      // Show loading state
      this.modalBody.innerHTML = '<div style="text-align: center; padding: 20px;">🔄 Connecting to extension...</div>';
      
      // Get pubkey from extension
      const pubkey = await extensionObj.getPublicKey();
      console.log('Extension provided pubkey:', pubkey);
      
      // Set extension method with the extension object
      this._setAuthMethod('extension', { pubkey, extension: extensionObj });
      
    } catch (error) {
      console.error('Extension login failed:', error);
      this._showError(`Extension login failed: ${error.message}`);
    }
  }

  _showLocalKeyScreen() {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Local Key';
    title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;';

    const createButton = document.createElement('button');
    createButton.textContent = 'Create New Key';
    createButton.onclick = () => this._createLocalKey();
    createButton.style.cssText = this._getButtonStyle();

    const importButton = document.createElement('button');
    importButton.textContent = 'Import Existing Key';
    importButton.onclick = () => this._showImportKeyForm();
    importButton.style.cssText = this._getButtonStyle() + 'margin-top: 12px;';

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = `
      display: block;
      margin-top: 20px;
      padding: 12px;
      background: #6b7280;
      color: white;
      border: none;
      border-radius: 6px;
      cursor: pointer;
    `;

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(createButton);
    this.modalBody.appendChild(importButton);
    this.modalBody.appendChild(backButton);
  }

  _createLocalKey() {
    try {
      const sk = window.NostrTools.generateSecretKey();
      const pk = window.NostrTools.getPublicKey(sk);
      const nsec = window.NostrTools.nip19.nsecEncode(sk);
      const npub = window.NostrTools.nip19.npubEncode(pk);

      this._showKeyDisplay(pk, nsec, 'created');
    } catch (error) {
      this._showError('Failed to create key: ' + error.message);
    }
  }

  _showImportKeyForm() {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Import Local Key';
    title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;';

    const description = document.createElement('p');
    description.textContent = 'Enter your secret key in either nsec or hex format:';
    description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;';

    const textarea = document.createElement('textarea');
    textarea.placeholder = 'Enter your secret key:\n• nsec1... (bech32 format)\n• 64-character hex string';
    textarea.style.cssText = `
      width: 100%;
      height: 100px;
      padding: 12px;
      border: 1px solid #d1d5db;
      border-radius: 6px;
      margin-bottom: 12px;
      resize: none;
      font-family: monospace;
      font-size: 14px;
      box-sizing: border-box;
    `;

    // Add real-time format detection
    const formatHint = document.createElement('div');
    formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;';
    
    textarea.oninput = () => {
      const value = textarea.value.trim();
      if (!value) {
        formatHint.textContent = '';
        return;
      }
      
      const format = this._detectKeyFormat(value);
      if (format === 'nsec') {
        formatHint.textContent = '✅ Valid nsec format detected';
        formatHint.style.color = '#059669';
      } else if (format === 'hex') {
        formatHint.textContent = '✅ Valid hex format detected';
        formatHint.style.color = '#059669';
      } else {
        formatHint.textContent = '❌ Invalid key format - must be nsec1... or 64-character hex';
        formatHint.style.color = '#dc2626';
      }
    };

    const importButton = document.createElement('button');
    importButton.textContent = 'Import Key';
    importButton.onclick = () => this._importLocalKey(textarea.value);
    importButton.style.cssText = this._getButtonStyle();

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._showLocalKeyScreen();
    backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(description);
    this.modalBody.appendChild(textarea);
    this.modalBody.appendChild(formatHint);
    this.modalBody.appendChild(importButton);
    this.modalBody.appendChild(backButton);
  }

  _detectKeyFormat(keyValue) {
    const trimmed = keyValue.trim();
    
    // Check for nsec format
    if (trimmed.startsWith('nsec1') && trimmed.length === 63) {
      try {
        window.NostrTools.nip19.decode(trimmed);
        return 'nsec';
      } catch {
        return 'invalid';
      }
    }
    
    // Check for hex format (64 characters, valid hex)
    if (trimmed.length === 64 && /^[a-fA-F0-9]{64}$/.test(trimmed)) {
      return 'hex';
    }
    
    return 'invalid';
  }

  _importLocalKey(keyValue) {
    try {
      const trimmed = keyValue.trim();
      if (!trimmed) {
        throw new Error('Please enter a secret key');
      }

      const format = this._detectKeyFormat(trimmed);
      let sk;

      if (format === 'nsec') {
        // Decode nsec format - this returns Uint8Array
        const decoded = window.NostrTools.nip19.decode(trimmed);
        if (decoded.type !== 'nsec') {
          throw new Error('Invalid nsec format');
        }
        sk = decoded.data; // This is already Uint8Array
      } else if (format === 'hex') {
        // Convert hex string to Uint8Array
        sk = this._hexToUint8Array(trimmed);
        // Test that it's a valid secret key by trying to get public key
        window.NostrTools.getPublicKey(sk);
      } else {
        throw new Error('Invalid key format. Please enter either nsec1... or 64-character hex string');
      }

      // Generate public key and encoded formats
      const pk = window.NostrTools.getPublicKey(sk);
      const nsec = window.NostrTools.nip19.nsecEncode(sk);
      const npub = window.NostrTools.nip19.npubEncode(pk);

      this._showKeyDisplay(pk, nsec, 'imported');
    } catch (error) {
      this._showError('Invalid key: ' + error.message);
    }
  }

  _hexToUint8Array(hex) {
    // Convert hex string to Uint8Array
    if (hex.length % 2 !== 0) {
      throw new Error('Invalid hex string length');
    }
    const bytes = new Uint8Array(hex.length / 2);
    for (let i = 0; i < bytes.length; i++) {
      bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
    }
    return bytes;
  }

  _showKeyDisplay(pubkey, nsec, action) {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = `Key ${action} successfully!`;
    title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;';

    const warningDiv = document.createElement('div');
    warningDiv.textContent = '⚠️ Save your secret key securely!';
    warningDiv.style.cssText = 'background: #fef3c7; color: #92400e; padding: 12px; border-radius: 6px; margin-bottom: 16px; font-size: 12px;';

    // Helper function to create copy button
    const createCopyButton = (text, label) => {
      const copyBtn = document.createElement('button');
      copyBtn.textContent = `Copy ${label}`;
      copyBtn.style.cssText = `
        margin-left: 8px;
        padding: 4px 8px;
        font-size: 10px;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        border: 1px solid var(--nl-primary-color);
        border-radius: 4px;
        cursor: pointer;
        font-family: var(--nl-font-family, 'Courier New', monospace);
      `;
      copyBtn.onclick = async (e) => {
        e.preventDefault();
        try {
          await navigator.clipboard.writeText(text);
          const originalText = copyBtn.textContent;
          copyBtn.textContent = '✓ Copied!';
          copyBtn.style.color = '#059669';
          setTimeout(() => {
            copyBtn.textContent = originalText;
            copyBtn.style.color = 'var(--nl-primary-color)';
          }, 2000);
        } catch (err) {
          console.error('Failed to copy:', err);
          copyBtn.textContent = '✗ Failed';
          copyBtn.style.color = '#dc2626';
          setTimeout(() => {
            copyBtn.textContent = originalText;
            copyBtn.style.color = 'var(--nl-primary-color)';
          }, 2000);
        }
      };
      return copyBtn;
    };

    // Convert pubkey to hex for verification
    const pubkeyHex = typeof pubkey === 'string' ? pubkey : Array.from(pubkey).map(b => b.toString(16).padStart(2, '0')).join('');
    
    // Decode nsec to get secret key as hex
    let secretKeyHex = '';
    try {
      const decoded = window.NostrTools.nip19.decode(nsec);
      secretKeyHex = Array.from(decoded.data).map(b => b.toString(16).padStart(2, '0')).join('');
    } catch (err) {
      console.error('Failed to decode nsec for hex display:', err);
    }

    // Secret Key Section
    const nsecSection = document.createElement('div');
    nsecSection.style.cssText = 'margin-bottom: 16px;';
    
    const nsecLabel = document.createElement('div');
    nsecLabel.innerHTML = '<strong>Your Secret Key (nsec):</strong>';
    nsecLabel.style.cssText = 'margin-bottom: 4px; font-size: 12px; font-weight: 600;';
    
    const nsecContainer = document.createElement('div');
    nsecContainer.style.cssText = 'display: flex; align-items: flex-start; margin-bottom: 8px;';
    
    const nsecCode = document.createElement('code');
    nsecCode.textContent = nsec;
    nsecCode.style.cssText = `
      flex: 1;
      word-break: break-all;
      background: #f3f4f6;
      padding: 6px;
      border-radius: 4px;
      font-size: 10px;
      line-height: 1.3;
      font-family: 'Courier New', monospace;
      display: block;
    `;
    
    nsecContainer.appendChild(nsecCode);
    nsecContainer.appendChild(createCopyButton(nsec, 'nsec'));
    nsecSection.appendChild(nsecLabel);
    nsecSection.appendChild(nsecContainer);

    // Secret Key Hex Section
    if (secretKeyHex) {
      const secretHexLabel = document.createElement('div');
      secretHexLabel.innerHTML = '<strong>Secret Key (hex):</strong>';
      secretHexLabel.style.cssText = 'margin-bottom: 4px; font-size: 12px; font-weight: 600;';
      
      const secretHexContainer = document.createElement('div');
      secretHexContainer.style.cssText = 'display: flex; align-items: flex-start; margin-bottom: 8px;';
      
      const secretHexCode = document.createElement('code');
      secretHexCode.textContent = secretKeyHex;
      secretHexCode.style.cssText = `
        flex: 1;
        word-break: break-all;
        background: #f3f4f6;
        padding: 6px;
        border-radius: 4px;
        font-size: 10px;
        line-height: 1.3;
        font-family: 'Courier New', monospace;
        display: block;
      `;
      
      secretHexContainer.appendChild(secretHexCode);
      secretHexContainer.appendChild(createCopyButton(secretKeyHex, 'hex'));
      nsecSection.appendChild(secretHexLabel);
      nsecSection.appendChild(secretHexContainer);
    }

    // Public Key Section
    const npubSection = document.createElement('div');
    npubSection.style.cssText = 'margin-bottom: 16px;';
    
    const npub = window.NostrTools.nip19.npubEncode(pubkey);
    
    const npubLabel = document.createElement('div');
    npubLabel.innerHTML = '<strong>Your Public Key (npub):</strong>';
    npubLabel.style.cssText = 'margin-bottom: 4px; font-size: 12px; font-weight: 600;';
    
    const npubContainer = document.createElement('div');
    npubContainer.style.cssText = 'display: flex; align-items: flex-start; margin-bottom: 8px;';
    
    const npubCode = document.createElement('code');
    npubCode.textContent = npub;
    npubCode.style.cssText = `
      flex: 1;
      word-break: break-all;
      background: #f3f4f6;
      padding: 6px;
      border-radius: 4px;
      font-size: 10px;
      line-height: 1.3;
      font-family: 'Courier New', monospace;
      display: block;
    `;
    
    npubContainer.appendChild(npubCode);
    npubContainer.appendChild(createCopyButton(npub, 'npub'));
    npubSection.appendChild(npubLabel);
    npubSection.appendChild(npubContainer);

    // Public Key Hex Section
    const pubHexLabel = document.createElement('div');
    pubHexLabel.innerHTML = '<strong>Public Key (hex):</strong>';
    pubHexLabel.style.cssText = 'margin-bottom: 4px; font-size: 12px; font-weight: 600;';
    
    const pubHexContainer = document.createElement('div');
    pubHexContainer.style.cssText = 'display: flex; align-items: flex-start;';
    
    const pubHexCode = document.createElement('code');
    pubHexCode.textContent = pubkeyHex;
    pubHexCode.style.cssText = `
      flex: 1;
      word-break: break-all;
      background: #f3f4f6;
      padding: 6px;
      border-radius: 4px;
      font-size: 10px;
      line-height: 1.3;
      font-family: 'Courier New', monospace;
      display: block;
    `;
    
    pubHexContainer.appendChild(pubHexCode);
    pubHexContainer.appendChild(createCopyButton(pubkeyHex, 'hex'));
    npubSection.appendChild(pubHexLabel);
    npubSection.appendChild(pubHexContainer);

    const continueButton = document.createElement('button');
    continueButton.textContent = 'Continue';
    continueButton.onclick = () => this._setAuthMethod('local', { secret: nsec, pubkey });
    continueButton.style.cssText = this._getButtonStyle();

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(warningDiv);
    this.modalBody.appendChild(nsecSection);
    this.modalBody.appendChild(npubSection);
    this.modalBody.appendChild(continueButton);
  }

  _setAuthMethod(method, options = {}) {
    // SINGLE-EXTENSION ARCHITECTURE: Handle method switching
    console.log('Modal: _setAuthMethod called with:', method, options);
    
    // CRITICAL: Never install facade for extension methods - leave window.nostr as the extension
    if (method === 'extension') {
      console.log('Modal: Extension method - NOT installing facade, leaving window.nostr as extension');
      
      // Save extension authentication state using global setAuthState function
      if (typeof window.setAuthState === 'function') {
        console.log('Modal: Saving extension auth state to storage');
        window.setAuthState({ method, ...options }, { isolateSession: this.options?.isolateSession });
      }
      
      // Emit auth method selection directly for extension
      const event = new CustomEvent('nlMethodSelected', {
        detail: { method, ...options }
      });
      window.dispatchEvent(event);
      
      this.close();
      return;
    }
    
    // For non-extension methods, we need to ensure WindowNostr facade is available
    console.log('Modal: Non-extension method detected:', method);
    
    // Check if we have a preserved extension but no WindowNostr facade installed
    const hasPreservedExtension = !!window.NOSTR_LOGIN_LITE?._instance?.preservedExtension;
    const hasWindowNostrFacade = window.nostr?.constructor?.name === 'WindowNostr';
    
    console.log('Modal: Method switching check:');
    console.log('  method:', method);
    console.log('  hasPreservedExtension:', hasPreservedExtension);
    console.log('  hasWindowNostrFacade:', hasWindowNostrFacade);
    console.log('  current window.nostr constructor:', window.nostr?.constructor?.name);
    
    // If we have a preserved extension but no facade, install facade for method switching
    if (hasPreservedExtension && !hasWindowNostrFacade) {
      console.log('Modal: Installing WindowNostr facade for method switching (non-extension authentication)');
      
      // Get the NostrLite instance and install facade with preserved extension
      const nostrLiteInstance = window.NOSTR_LOGIN_LITE?._instance;
      if (nostrLiteInstance && typeof nostrLiteInstance._installFacade === 'function') {
        const preservedExtension = nostrLiteInstance.preservedExtension;
        console.log('Modal: Installing facade with preserved extension:', preservedExtension?.constructor?.name);
        
        nostrLiteInstance._installFacade(preservedExtension);
        console.log('Modal: WindowNostr facade installed for method switching');
      } else {
        console.error('Modal: Cannot access NostrLite instance or _installFacade method');
      }
    }
    
    // If no extension at all, ensure facade is installed for local/NIP-46/readonly methods
    else if (!hasPreservedExtension && !hasWindowNostrFacade) {
      console.log('Modal: Installing WindowNostr facade for non-extension methods (no extension detected)');
      
      const nostrLiteInstance = window.NOSTR_LOGIN_LITE?._instance;
      if (nostrLiteInstance && typeof nostrLiteInstance._installFacade === 'function') {
        nostrLiteInstance._installFacade();
        console.log('Modal: WindowNostr facade installed for non-extension methods');
      }
    }
    
    // Emit auth method selection
    const event = new CustomEvent('nlMethodSelected', {
      detail: { method, ...options }
    });
    window.dispatchEvent(event);

    this.close();
  }

  _showError(message) {
    this.modalBody.innerHTML = '';

    const errorDiv = document.createElement('div');
    errorDiv.style.cssText = 'background: #fee2e2; color: #dc2626; padding: 16px; border-radius: 6px; margin-bottom: 16px;';
    errorDiv.innerHTML = `<strong>Error:</strong> ${message}`;

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary');

    this.modalBody.appendChild(errorDiv);
    this.modalBody.appendChild(backButton);
  }

  _showExtensionRequired() {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Browser Extension Required';
    title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;';

    const message = document.createElement('p');
    message.innerHTML = `
      Please install a Nostr browser extension and refresh the page.<br><br>
      <strong>Important:</strong> If you have multiple extensions installed, please disable all but one to avoid conflicts.
      <br><br>
      Popular extensions: Alby, nos2x, Flamingo
    `;
    message.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px; line-height: 1.4;';

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary');

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(message);
    this.modalBody.appendChild(backButton);
  }

  _showConnectScreen() {
    this.modalBody.innerHTML = '';

    const description = document.createElement('p');
    description.textContent = 'Connect to a remote signer (bunker) server to use its keys for signing.';
    description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;';

    const formGroup = document.createElement('div');
    formGroup.style.cssText = 'margin-bottom: 20px;';

    const label = document.createElement('label');
    label.textContent = 'Bunker Public Key:';
    label.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;';

    const pubkeyInput = document.createElement('input');
    pubkeyInput.type = 'text';
    pubkeyInput.placeholder = 'bunker://pubkey?relay=..., bunker:hex, hex, or npub...';
    pubkeyInput.style.cssText = `
      width: 100%;
      padding: 12px;
      border: 1px solid #d1d5db;
      border-radius: 6px;
      margin-bottom: 12px;
      font-family: monospace;
      box-sizing: border-box;
    `;

    // Add real-time bunker key validation
    const formatHint = document.createElement('div');
    formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;';

    const connectButton = document.createElement('button');
    connectButton.textContent = 'Connect to Bunker';
    connectButton.disabled = true;
    connectButton.onclick = () => {
      if (!connectButton.disabled) {
        this._handleNip46Connect(pubkeyInput.value);
      }
    };
    
    // Set initial disabled state
    connectButton.style.cssText = `
      display: block;
      width: 100%;
      padding: 12px;
      border: var(--nl-border-width) solid var(--nl-muted-color);
      border-radius: var(--nl-border-radius);
      font-size: 16px;
      font-weight: 500;
      cursor: not-allowed;
      transition: all 0.2s;
      font-family: var(--nl-font-family, 'Courier New', monospace);
      background: var(--nl-secondary-color);
      color: var(--nl-muted-color);
      margin-bottom: 12px;
    `;

    pubkeyInput.oninput = () => {
      const value = pubkeyInput.value.trim();
      if (!value) {
        formatHint.textContent = '';
        // Disable button
        connectButton.disabled = true;
        connectButton.style.borderColor = 'var(--nl-muted-color)';
        connectButton.style.color = 'var(--nl-muted-color)';
        connectButton.style.cursor = 'not-allowed';
        return;
      }
      
      const isValid = this._validateBunkerKey(value);
      if (isValid) {
        formatHint.textContent = '✅ Valid bunker connection format detected';
        formatHint.style.color = '#059669';
        // Enable button
        connectButton.disabled = false;
        connectButton.style.borderColor = 'var(--nl-primary-color)';
        connectButton.style.color = 'var(--nl-primary-color)';
        connectButton.style.cursor = 'pointer';
      } else {
        formatHint.textContent = '❌ Invalid format - must be bunker://, npub, or 64-char hex';
        formatHint.style.color = '#dc2626';
        // Disable button
        connectButton.disabled = true;
        connectButton.style.borderColor = 'var(--nl-muted-color)';
        connectButton.style.color = 'var(--nl-muted-color)';
        connectButton.style.cursor = 'not-allowed';
      }
    };

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';

    formGroup.appendChild(label);
    formGroup.appendChild(pubkeyInput);
    formGroup.appendChild(formatHint);

    this.modalBody.appendChild(description);
    this.modalBody.appendChild(formGroup);
    this.modalBody.appendChild(connectButton);
    this.modalBody.appendChild(backButton);
  }

  _validateBunkerKey(bunkerKey) {
    try {
      const trimmed = bunkerKey.trim();
      
      // Check for bunker:// format
      if (trimmed.startsWith('bunker://')) {
        // Should have format: bunker://pubkey or bunker://pubkey?param=value
        const match = trimmed.match(/^bunker:\/\/([0-9a-fA-F]{64})(\?.*)?$/);
        return !!match;
      }
      
      // Check for npub format
      if (trimmed.startsWith('npub1') && trimmed.length === 63) {
        try {
          if (window.NostrTools?.nip19) {
            const decoded = window.NostrTools.nip19.decode(trimmed);
            return decoded.type === 'npub';
          }
        } catch {
          return false;
        }
      }
      
      // Check for hex format (64 characters, valid hex)
      if (trimmed.length === 64 && /^[a-fA-F0-9]{64}$/.test(trimmed)) {
        return true;
      }
      
      return false;
    } catch (error) {
      console.log('Bunker key validation failed:', error.message);
      return false;
    }
  }

  _handleNip46Connect(bunkerPubkey) {
    if (!bunkerPubkey || !bunkerPubkey.length) {
      this._showError('Bunker pubkey is required');
      return;
    }

    this._showNip46Connecting(bunkerPubkey);
    this._performNip46Connect(bunkerPubkey);
  }

  _showNip46Connecting(bunkerPubkey) {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Connecting to Remote Signer...';
    title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #059669;';

    const description = document.createElement('p');
    description.textContent = 'Establishing secure connection to your remote signer.';
    description.style.cssText = 'margin-bottom: 20px; color: #6b7280;';

    // Normalize bunker pubkey for display (= show original format if bunker: prefix)
    const displayPubkey = bunkerPubkey.startsWith('bunker:') || bunkerPubkey.startsWith('npub') || bunkerPubkey.length === 64 ? bunkerPubkey : bunkerPubkey;

    const bunkerInfo = document.createElement('div');
    bunkerInfo.style.cssText = 'background: #f1f5f9; padding: 12px; border-radius: 6px; margin-bottom: 20px; font-size: 14px;';
    bunkerInfo.innerHTML = `
      <strong>Connecting to bunker:</strong><br>
      Connection: <code style="word-break: break-all;">${displayPubkey}</code><br>
      <small style="color: #6b7280;">Connection string contains all necessary relay information.</small>
    `;

    const connectingDiv = document.createElement('div');
    connectingDiv.style.cssText = 'text-align: center; color: #6b7280;';
    connectingDiv.innerHTML = `
      <div style="font-size: 24px; margin-bottom: 10px;">⏳</div>
      <div>Please wait while we establish the connection...</div>
      <div style="font-size: 12px; margin-top: 10px;">This may take a few seconds</div>
    `;

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(description);
    this.modalBody.appendChild(bunkerInfo);
    this.modalBody.appendChild(connectingDiv);
  }

  async _performNip46Connect(bunkerPubkey) {
    try {
      console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);

      // Check if nostr-tools NIP-46 is available
      if (!window.NostrTools?.nip46) {
        throw new Error('nostr-tools NIP-46 module not available');
      }

      // Use nostr-tools to parse bunker input - this handles all formats correctly
      console.log('Parsing bunker input with nostr-tools...');
      const bunkerPointer = await window.NostrTools.nip46.parseBunkerInput(bunkerPubkey);

      if (!bunkerPointer) {
        throw new Error('Unable to parse bunker connection string or resolve NIP-05 identifier');
      }

      console.log('Parsed bunker pointer:', bunkerPointer);

      // Create local client keypair for this session
      const localSecretKey = window.NostrTools.generateSecretKey();
      console.log('Generated local client keypair for NIP-46 session');

      // Use nostr-tools BunkerSigner factory method (not constructor - it's private)
      console.log('Creating nip46 BunkerSigner...');
      const signer = window.NostrTools.nip46.BunkerSigner.fromBunker(localSecretKey, bunkerPointer, {
        onauth: (url) => {
          console.log('Received auth URL from bunker:', url);
          // Open auth URL in popup or redirect
          window.open(url, '_blank', 'width=600,height=800');
        }
      });

      console.log('NIP-46 BunkerSigner created successfully');

      // Skip ping test - NIP-46 works through relays, not direct connection
      // Try to connect directly (this may trigger auth flow)
      console.log('Attempting NIP-46 connect...');
      await signer.connect();
      console.log('NIP-46 connect successful');

      // Get the user's public key from the bunker
      console.log('Getting public key from bunker...');
      const userPubkey = await signer.getPublicKey();
      console.log('NIP-46 user public key:', userPubkey);

      // Store the NIP-46 authentication info
      const nip46Info = {
        pubkey: userPubkey,
        signer: {
          method: 'nip46',
          remotePubkey: bunkerPointer.pubkey,
          bunkerSigner: signer,
          secret: bunkerPointer.secret,
          relays: bunkerPointer.relays
        }
      };

      console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!');

      // Set as current auth method
      this._setAuthMethod('nip46', nip46Info);
      return;

    } catch (error) {
      console.error('NIP-46 connection failed:', error);
      this._showNip46Error(error.message);
    }
  }

  _showNip46Error(message) {
    this.modalBody.innerHTML = '';

    const title = document.createElement('h3');
    title.textContent = 'Connection Failed';
    title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600; color: #dc2626;';

    const errorMsg = document.createElement('p');
    errorMsg.textContent = `Unable to connect to remote signer: ${message}`;
    errorMsg.style.cssText = 'margin-bottom: 20px; color: #6b7280;';

    const retryButton = document.createElement('button');
    retryButton.textContent = 'Try Again';
    retryButton.onclick = () => this._showConnectScreen();
    retryButton.style.cssText = this._getButtonStyle();

    const backButton = document.createElement('button');
    backButton.textContent = 'Back to Options';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';

    this.modalBody.appendChild(title);
    this.modalBody.appendChild(errorMsg);
    this.modalBody.appendChild(retryButton);
    this.modalBody.appendChild(backButton);
  }

  _handleReadonly() {
    // Set read-only mode
    this._setAuthMethod('readonly');
  }

  _showSeedPhraseScreen() {
    this.modalBody.innerHTML = '';

    const description = document.createElement('p');
    description.innerHTML = 'Enter your 12 or 24-word mnemonic seed phrase to derive Nostr accounts, or <span id="generate-new" style="text-decoration: underline; cursor: pointer; color: var(--nl-primary-color);">generate new</span>.';
    description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;';

    const textarea = document.createElement('textarea');
    // Remove default placeholder text as requested
    textarea.placeholder = '';
    textarea.style.cssText = `
      width: 100%;
      height: 100px;
      padding: 12px;
      border: 1px solid #d1d5db;
      border-radius: 6px;
      margin-bottom: 12px;
      resize: none;
      font-family: monospace;
      font-size: 14px;
      box-sizing: border-box;
    `;

    // Add real-time mnemonic validation
    const formatHint = document.createElement('div');
    formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;';
    
    const importButton = document.createElement('button');
    importButton.textContent = 'Import Accounts';
    importButton.disabled = true;
    importButton.onclick = () => {
      if (!importButton.disabled) {
        this._importFromSeedPhrase(textarea.value);
      }
    };
    
    // Set initial disabled state
    importButton.style.cssText = `
      display: block;
      width: 100%;
      padding: 12px;
      border: var(--nl-border-width) solid var(--nl-muted-color);
      border-radius: var(--nl-border-radius);
      font-size: 16px;
      font-weight: 500;
      cursor: not-allowed;
      transition: all 0.2s;
      font-family: var(--nl-font-family, 'Courier New', monospace);
      background: var(--nl-secondary-color);
      color: var(--nl-muted-color);
    `;
    
    textarea.oninput = () => {
      const value = textarea.value.trim();
      if (!value) {
        formatHint.textContent = '';
        // Disable button
        importButton.disabled = true;
        importButton.style.borderColor = 'var(--nl-muted-color)';
        importButton.style.color = 'var(--nl-muted-color)';
        importButton.style.cursor = 'not-allowed';
        return;
      }
      
      const isValid = this._validateMnemonic(value);
      if (isValid) {
        const wordCount = value.split(/\s+/).length;
        formatHint.textContent = `✅ Valid ${wordCount}-word mnemonic detected`;
        formatHint.style.color = '#059669';
        // Enable button
        importButton.disabled = false;
        importButton.style.borderColor = 'var(--nl-primary-color)';
        importButton.style.color = 'var(--nl-primary-color)';
        importButton.style.cursor = 'pointer';
      } else {
        formatHint.textContent = '❌ Invalid mnemonic - must be 12 or 24 valid BIP-39 words';
        formatHint.style.color = '#dc2626';
        // Disable button
        importButton.disabled = true;
        importButton.style.borderColor = 'var(--nl-muted-color)';
        importButton.style.color = 'var(--nl-muted-color)';
        importButton.style.cursor = 'not-allowed';
      }
    };

    const backButton = document.createElement('button');
    backButton.textContent = 'Back';
    backButton.onclick = () => this._renderLoginOptions();
    backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';

    this.modalBody.appendChild(description);
    this.modalBody.appendChild(textarea);
    this.modalBody.appendChild(formatHint);
    this.modalBody.appendChild(importButton);
    this.modalBody.appendChild(backButton);

    // Add click handler for the "generate new" link
    const generateLink = document.getElementById('generate-new');
    if (generateLink) {
      generateLink.addEventListener('mouseenter', () => {
        generateLink.style.color = 'var(--nl-accent-color)';
      });
      generateLink.addEventListener('mouseleave', () => {
        generateLink.style.color = 'var(--nl-primary-color)';
      });
      generateLink.addEventListener('click', () => {
        this._generateNewSeedPhrase(textarea, formatHint);
      });
    }
  }

  _generateNewSeedPhrase(textarea, formatHint) {
    try {
      // Check if NIP-06 is available
      if (!window.NostrTools?.nip06) {
        throw new Error('NIP-06 not available in bundle');
      }

      // Generate a random 12-word mnemonic using NostrTools
      const mnemonic = window.NostrTools.nip06.generateSeedWords();
      
      // Set the generated mnemonic in the textarea
      textarea.value = mnemonic;
      
      // Trigger the oninput event to properly validate and enable the button
      if (textarea.oninput) {
        textarea.oninput();
      }
      
      console.log('Generated new seed phrase:', mnemonic.split(/\s+/).length, 'words');
      
    } catch (error) {
      console.error('Failed to generate seed phrase:', error);
      formatHint.textContent = '❌ Failed to generate seed phrase - NIP-06 not available';
      formatHint.style.color = '#dc2626';
    }
  }

  _validateMnemonic(mnemonic) {
    try {
      // Check if NIP-06 is available
      if (!window.NostrTools?.nip06) {
        console.error('NIP-06 not available in bundle');
        return false;
      }

      const words = mnemonic.trim().split(/\s+/);
      
      // Must be 12 or 24 words
      if (words.length !== 12 && words.length !== 24) {
        return false;
      }

      // Try to validate using NostrTools nip06 - this will throw if invalid
      window.NostrTools.nip06.privateKeyFromSeedWords(mnemonic, '', 0);
      return true;
    } catch (error) {
      console.log('Mnemonic validation failed:', error.message);
      return false;
    }
  }

  _importFromSeedPhrase(mnemonic) {
    try {
      const trimmed = mnemonic.trim();
      if (!trimmed) {
        throw new Error('Please enter a mnemonic seed phrase');
      }

      // Validate the mnemonic
      if (!this._validateMnemonic(trimmed)) {
        throw new Error('Invalid mnemonic. Please enter a valid 12 or 24-word BIP-39 seed phrase');
      }

      // Generate accounts 0-5 using NIP-06
      const accounts = [];
      for (let i = 0; i < 6; i++) {
        try {
          const privateKey = window.NostrTools.nip06.privateKeyFromSeedWords(trimmed, '', i);
          const publicKey = window.NostrTools.getPublicKey(privateKey);
          const nsec = window.NostrTools.nip19.nsecEncode(privateKey);
          const npub = window.NostrTools.nip19.npubEncode(publicKey);

          accounts.push({
            index: i,
            privateKey,
            publicKey,
            nsec,
            npub
          });
        } catch (error) {
          console.error(`Failed to derive account ${i}:`, error);
        }
      }

      if (accounts.length === 0) {
        throw new Error('Failed to derive any accounts from seed phrase');
      }

      console.log(`Successfully derived ${accounts.length} accounts from seed phrase`);
      this._showAccountSelection(accounts);

    } catch (error) {
      console.error('Seed phrase import failed:', error);
      this._showError('Seed phrase import failed: ' + error.message);
    }
  }

  _showAccountSelection(accounts) {
    this.modalBody.innerHTML = '';

    const description = document.createElement('p');
    description.textContent = `Select which account to use (${accounts.length} accounts derived from seed phrase):`;
    description.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px;';

    this.modalBody.appendChild(description);

    // Create table for account selection
    const table = document.createElement('table');
    table.style.cssText = `
      width: 100%;
      border-collapse: collapse;
      margin-bottom: 20px;
      font-family: var(--nl-font-family, 'Courier New', monospace);
      font-size: 12px;
    `;

    // Table header
    const thead = document.createElement('thead');
    thead.innerHTML = `
      <tr style="background: #f3f4f6;">
        <th style="padding: 8px; text-align: center; border: 1px solid #d1d5db; font-weight: bold;">#</th>
        <th style="padding: 8px; text-align: center; border: 1px solid #d1d5db; font-weight: bold;">Use</th>
      </tr>
    `;
    table.appendChild(thead);

    // Table body
    const tbody = document.createElement('tbody');
    accounts.forEach(account => {
      const row = document.createElement('tr');
      row.style.cssText = 'border: 1px solid #d1d5db;';
      
      const indexCell = document.createElement('td');
      indexCell.textContent = account.index;
      indexCell.style.cssText = 'padding: 8px; text-align: center; border: 1px solid #d1d5db; font-weight: bold;';

      const actionCell = document.createElement('td');
      actionCell.style.cssText = 'padding: 8px; border: 1px solid #d1d5db;';
      
      // Show truncated npub in the button
      const truncatedNpub = `${account.npub.slice(0, 12)}...${account.npub.slice(-8)}`;
      
      const selectButton = document.createElement('button');
      selectButton.textContent = truncatedNpub;
      selectButton.onclick = () => this._selectAccount(account);
      selectButton.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        font-size: 11px;
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
        border: 1px solid var(--nl-primary-color);
        border-radius: 4px;
        cursor: pointer;
        font-family: 'Courier New', monospace;
        text-align: center;
      `;
      selectButton.onmouseover = () => {
        selectButton.style.borderColor = 'var(--nl-accent-color)';
      };
      selectButton.onmouseout = () => {
        selectButton.style.borderColor = 'var(--nl-primary-color)';
      };

      actionCell.appendChild(selectButton);
      
      row.appendChild(indexCell);
      row.appendChild(actionCell);
      tbody.appendChild(row);
    });
    table.appendChild(tbody);

    this.modalBody.appendChild(table);

    // Back button
    const backButton = document.createElement('button');
    backButton.textContent = 'Back to Seed Phrase';
    backButton.onclick = () => this._showSeedPhraseScreen();
    backButton.style.cssText = this._getButtonStyle('secondary');

    this.modalBody.appendChild(backButton);
  }

  _selectAccount(account) {
    console.log('Selected account:', account.index, account.npub);
    
    // Use the same auth method as local keys, but with seedphrase identifier
    this._setAuthMethod('local', {
      secret: account.nsec,
      pubkey: account.publicKey,
      source: 'seedphrase',
      accountIndex: account.index
    });
  }

  _showOtpScreen() {
    // Placeholder for OTP functionality
    this._showError('OTP/DM not yet implemented - coming soon!');
  }

  _getButtonStyle(type = 'primary') {
    const baseStyle = `
      display: block;
      width: 100%;
      padding: 12px;
      border: var(--nl-border-width) solid var(--nl-primary-color);
      border-radius: var(--nl-border-radius);
      font-size: 16px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s;
      font-family: var(--nl-font-family, 'Courier New', monospace);
    `;

    if (type === 'primary') {
      return baseStyle + `
        background: var(--nl-secondary-color);
        color: var(--nl-primary-color);
      `;
    } else {
      return baseStyle + `
        background: #cccccc;
        color: var(--nl-primary-color);
      `;
    }
  }

  // Public API
  static init(options) {
    if (Modal.instance) return Modal.instance;
    Modal.instance = new Modal(options);
    return Modal.instance;
  }

  static getInstance() {
    return Modal.instance;
  }
}

// Initialize global instance
let modalInstance = null;

window.addEventListener('load', () => {
  modalInstance = new Modal();
});


// ======================================
// FloatingTab Component (Recovered from git history)
// ======================================

class FloatingTab {
  constructor(modal, options = {}) {
    this.modal = modal;
    this.options = {
      enabled: true,
      hPosition: 1.0, // 0.0 = left, 1.0 = right
      vPosition: 0.5, // 0.0 = top, 1.0 = bottom
      offset: { x: 0, y: 0 },
      appearance: {
        style: 'pill', // 'pill', 'square', 'circle'
        theme: 'auto', // 'auto', 'light', 'dark'
        icon: '',
        text: 'Login',
        iconOnly: false
      },
      behavior: {
        hideWhenAuthenticated: true,
        showUserInfo: true,
        autoSlide: true,
        persistent: false
      },
      getUserInfo: false,
      getUserRelay: [],
      ...options
    };

    this.userProfile = null;
    this.container = null;
    this.isVisible = false;

    if (this.options.enabled) {
      this._init();
    }
  }

  _init() {
    console.log('FloatingTab: Initializing with options:', this.options);
    this._createContainer();
    this._setupEventListeners();
    this._updateAppearance();
    this._position();
    this.show();
  }

  // Get authentication state from authoritative source (Global Storage-Based Function)
  _getAuthState() {
    return window.NOSTR_LOGIN_LITE?.getAuthState?.() || null;
  }


  _createContainer() {
    // Remove existing floating tab if any
    const existingTab = document.getElementById('nl-floating-tab');
    if (existingTab) {
      existingTab.remove();
    }

    this.container = document.createElement('div');
    this.container.id = 'nl-floating-tab';
    this.container.className = 'nl-floating-tab';
    
    // Base styles - positioning and behavior
    this.container.style.cssText = `
      position: fixed;
      z-index: 9999;
      cursor: pointer;
      user-select: none;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s ease;
      font-size: 14px;
      font-weight: 500;
      padding: 8px 16px;
      min-width: 80px;
      max-width: 200px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    `;

    document.body.appendChild(this.container);
  }

  _setupEventListeners() {
    if (!this.container) return;

    // Click handler
    this.container.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
      this._handleClick();
    });

    // Hover effects
    this.container.addEventListener('mouseenter', () => {
      if (this.options.behavior.autoSlide) {
        this._slideIn();
      }
    });

    this.container.addEventListener('mouseleave', () => {
      if (this.options.behavior.autoSlide) {
        this._slideOut();
      }
    });

    // Listen for authentication events
    window.addEventListener('nlMethodSelected', (e) => {
      console.log('🔍 FloatingTab: Authentication method selected event received');
      console.log('🔍 FloatingTab: Event detail:', e.detail);
      this._handleAuth(e.detail);
    });

    window.addEventListener('nlAuthRestored', (e) => {
      console.log('🔍 FloatingTab: ✅ Authentication restored event received');
      console.log('🔍 FloatingTab: Event detail:', e.detail);
      console.log('🔍 FloatingTab: Calling _handleAuth with restored data...');
      this._handleAuth(e.detail);
    });

    window.addEventListener('nlLogout', () => {
      console.log('🔍 FloatingTab: Logout event received');
      this._handleLogout();
    });
    
    // Check for existing authentication state on initialization
    window.addEventListener('load', () => {
      setTimeout(() => {
        this._checkExistingAuth();
      }, 1000); // Wait 1 second for all initialization to complete
    });
  }

  // Check for existing authentication on page load
  async _checkExistingAuth() {
    console.log('🔍 FloatingTab: === _checkExistingAuth START ===');
    
    try {
      const storageKey = 'nostr_login_lite_auth';
      let storedAuth = null;
      
      // Try sessionStorage first, then localStorage
      if (sessionStorage.getItem(storageKey)) {
        storedAuth = JSON.parse(sessionStorage.getItem(storageKey));
        console.log('🔍 FloatingTab: Found auth in sessionStorage:', storedAuth.method);
      } else if (localStorage.getItem(storageKey)) {
        storedAuth = JSON.parse(localStorage.getItem(storageKey));
        console.log('🔍 FloatingTab: Found auth in localStorage:', storedAuth.method);
      }
      
      if (storedAuth) {
        // Check if stored auth is not expired
        const maxAge = storedAuth.method === 'extension' ? 60 * 60 * 1000 : 24 * 60 * 60 * 1000;
        if (Date.now() - storedAuth.timestamp <= maxAge) {
          console.log('🔍 FloatingTab: Found valid stored auth, simulating auth event');
          
          // Create auth data object for FloatingTab
          const authData = {
            method: storedAuth.method,
            pubkey: storedAuth.pubkey
          };
          
          // For extensions, try to find the extension
          if (storedAuth.method === 'extension') {
            if (window.nostr && window.nostr.constructor?.name !== 'WindowNostr') {
              authData.extension = window.nostr;
            }
          }
          
          await this._handleAuth(authData);
        } else {
          console.log('🔍 FloatingTab: Stored auth expired, clearing');
          sessionStorage.removeItem(storageKey);
          localStorage.removeItem(storageKey);
        }
      } else {
        console.log('🔍 FloatingTab: No existing authentication found');
      }
      
    } catch (error) {
      console.error('🔍 FloatingTab: Error checking existing auth:', error);
    }
    
    console.log('🔍 FloatingTab: === _checkExistingAuth END ===');
  }

  _handleClick() {
    console.log('FloatingTab: Clicked');
    
    const authState = this._getAuthState();
    if (authState && this.options.behavior.showUserInfo) {
      // Show user menu or profile options
      this._showUserMenu();
    } else {
      // Always open login modal (consistent with login buttons)
      if (this.modal) {
        this.modal.open({ startScreen: 'login' });
      }
    }
  }

  // Check if object is a real extension (same logic as NostrLite._isRealExtension)
  _isRealExtension(obj) {
    if (!obj || typeof obj !== 'object') {
      return false;
    }
    
    // Must have required Nostr methods
    if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') {
      return false;
    }

    // Exclude our own library classes
    const constructorName = obj.constructor?.name;
    if (constructorName === 'WindowNostr' || constructorName === 'NostrLite') {
      return false;
    }

    // Exclude NostrTools library object
    if (obj === window.NostrTools) {
      return false;
    }

    // Conservative check: Look for common extension characteristics
    const extensionIndicators = [
      '_isEnabled', 'enabled', 'kind', '_eventEmitter', '_scope',
      '_requests', '_pubkey', 'name', 'version', 'description'
    ];
    
    const hasIndicators = extensionIndicators.some(prop => obj.hasOwnProperty(prop));
    
    // Additional check: Extensions often have specific constructor patterns
    const hasExtensionConstructor = constructorName &&
                                  constructorName !== 'Object' &&
                                  constructorName !== 'Function';

    return hasIndicators || hasExtensionConstructor;
  }

  // Try to login with extension and trigger proper persistence
  async _tryExtensionLogin(extension) {
    try {
      console.log('FloatingTab: Attempting extension login');
      
      // Get pubkey from extension
      const pubkey = await extension.getPublicKey();
      console.log('FloatingTab: Extension provided pubkey:', pubkey);
      
      // Create extension auth data
      const extensionAuth = {
        method: 'extension',
        pubkey: pubkey,
        extension: extension
      };
      
      // **CRITICAL FIX**: Dispatch nlMethodSelected event to trigger persistence
      console.log('FloatingTab: Dispatching nlMethodSelected for persistence');
      if (typeof window !== 'undefined') {
        window.dispatchEvent(new CustomEvent('nlMethodSelected', {
          detail: extensionAuth
        }));
      }
      
      // Also call our local _handleAuth for UI updates
      await this._handleAuth(extensionAuth);
      
    } catch (error) {
      console.error('FloatingTab: Extension login failed:', error);
      // Fall back to opening modal
      if (this.modal) {
        this.modal.open({ startScreen: 'login' });
      }
    }
  }

  async _handleAuth(authData) {
    console.log('🔍 FloatingTab: === _handleAuth START ===');
    console.log('🔍 FloatingTab: authData received:', authData);
    
    // Wait a brief moment for WindowNostr to process the authentication
    setTimeout(async () => {
      console.log('🔍 FloatingTab: Checking authentication state from authoritative source...');
      
      const authState = this._getAuthState();
      const isAuthenticated = !!authState;
      
      console.log('🔍 FloatingTab: Authoritative auth state:', authState);
      console.log('🔍 FloatingTab: Is authenticated:', isAuthenticated);
      
      if (isAuthenticated) {
        console.log('🔍 FloatingTab: ✅ Authentication verified from authoritative source');
      } else {
        console.error('🔍 FloatingTab: ❌ Authentication not found in authoritative source');
      }
      
      // Fetch user profile if enabled and we have a pubkey
      if (this.options.getUserInfo && authData.pubkey) {
        console.log('🔍 FloatingTab: getUserInfo enabled, fetching profile for:', authData.pubkey);
        try {
          const profile = await this._fetchUserProfile(authData.pubkey);
          this.userProfile = profile;
          console.log('🔍 FloatingTab: User profile fetched:', profile);
        } catch (error) {
          console.warn('🔍 FloatingTab: Failed to fetch user profile:', error);
          this.userProfile = null;
        }
      } else {
        console.log('🔍 FloatingTab: getUserInfo disabled or no pubkey, skipping profile fetch');
      }
      
      this._updateAppearance(); // Update UI based on authoritative state
      
      console.log('🔍 FloatingTab: hideWhenAuthenticated option:', this.options.behavior.hideWhenAuthenticated);
      
      if (this.options.behavior.hideWhenAuthenticated && isAuthenticated) {
        console.log('🔍 FloatingTab: Hiding tab (hideWhenAuthenticated=true and authenticated)');
        this.hide();
      } else {
        console.log('🔍 FloatingTab: Keeping tab visible');
      }
      
    }, 500); // Wait 500ms for WindowNostr to complete authentication processing
    
    console.log('🔍 FloatingTab: === _handleAuth END ===');
  }

  _handleLogout() {
    console.log('FloatingTab: Handling logout');
    this.userProfile = null;
    
    if (this.options.behavior.hideWhenAuthenticated) {
      this.show();
    }
    
    this._updateAppearance();
  }

  _showUserMenu() {
    // Simple user menu - could be expanded
    const menu = document.createElement('div');
    menu.style.cssText = `
      position: fixed;
      background: var(--nl-secondary-color);
      border: var(--nl-border-width) solid var(--nl-primary-color);
      border-radius: var(--nl-border-radius);
      padding: 12px;
      z-index: 10000;
      font-family: var(--nl-font-family);
      box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    `;

    // Position near the floating tab
    const tabRect = this.container.getBoundingClientRect();
    if (this.options.hPosition > 0.5) {
      // Tab is on right side, show menu to the left
      menu.style.right = (window.innerWidth - tabRect.left) + 'px';
    } else {
      // Tab is on left side, show menu to the right
      menu.style.left = tabRect.right + 'px';
    }
    menu.style.top = tabRect.top + 'px';

    // Menu content - use _getAuthState() as single source of truth
    const authState = this._getAuthState();
    let userDisplay;
    
    if (authState?.pubkey) {
      // Use profile name if available, otherwise pubkey
      if (this.userProfile?.name || this.userProfile?.display_name) {
        const userName = this.userProfile.name || this.userProfile.display_name;
        userDisplay = userName.length > 16 ? `${userName.slice(0, 16)}...` : userName;
      } else {
        userDisplay = `${authState.pubkey.slice(0, 8)}...${authState.pubkey.slice(-4)}`;
      }
    } else {
      userDisplay = 'Authenticated';
    }

    menu.innerHTML = `
      <div style="margin-bottom: 8px; font-weight: bold; color: var(--nl-primary-color);">${userDisplay}</div>
      <button onclick="window.NOSTR_LOGIN_LITE.logout(); this.parentElement.remove();"
              style="background: var(--nl-secondary-color); color: var(--nl-primary-color);
                     border: 1px solid var(--nl-primary-color); border-radius: 4px;
                     padding: 6px 12px; cursor: pointer; width: 100%;">
        Logout
      </button>
    `;

    document.body.appendChild(menu);

    // Auto-remove menu after delay or on outside click
    const removeMenu = () => menu.remove();
    setTimeout(removeMenu, 5000);
    
    document.addEventListener('click', function onOutsideClick(e) {
      if (!menu.contains(e.target) && e.target !== this.container) {
        removeMenu();
        document.removeEventListener('click', onOutsideClick);
      }
    });
  }

  _updateAppearance() {
    if (!this.container) return;

    // Query authoritative source for all state information
    const authState = this._getAuthState();
    const isAuthenticated = authState !== null;

    // Update content
    if (isAuthenticated && this.options.behavior.showUserInfo) {
      let display;
      
      // Use profile name if available, otherwise fall back to pubkey
      if (this.userProfile?.name || this.userProfile?.display_name) {
        const userName = this.userProfile.name || this.userProfile.display_name;
        display = this.options.appearance.iconOnly
          ? userName.slice(0, 8)
          : userName;
      } else if (authState?.pubkey) {
        // Fallback to pubkey display
        display = this.options.appearance.iconOnly
          ? authState.pubkey.slice(0, 6)
          : `${authState.pubkey.slice(0, 6)}...`;
      } else {
        display = this.options.appearance.iconOnly ? 'User' : 'Authenticated';
      }
      
      this.container.textContent = display;
      this.container.className = 'nl-floating-tab nl-floating-tab--logged-in';
    } else {
      const display = this.options.appearance.iconOnly ?
        this.options.appearance.icon :
        (this.options.appearance.icon ? `${this.options.appearance.icon} ${this.options.appearance.text}` : this.options.appearance.text);
      
      this.container.textContent = display;
      this.container.className = 'nl-floating-tab nl-floating-tab--logged-out';
    }

    // Apply appearance styles based on current state
    this._applyThemeStyles();
  }

  _applyThemeStyles() {
    if (!this.container) return;

    // The CSS classes will handle the theming through CSS custom properties
    // Additional style customizations can be added here if needed
    
    // Apply style variant
    if (this.options.appearance.style === 'circle') {
      this.container.style.borderRadius = '50%';
      this.container.style.width = '48px';
      this.container.style.height = '48px';
      this.container.style.minWidth = '48px';
      this.container.style.padding = '0';
    } else if (this.options.appearance.style === 'square') {
      this.container.style.borderRadius = '4px';
    } else {
      // pill style (default)
      this.container.style.borderRadius = 'var(--nl-border-radius)';
    }
  }

  async _fetchUserProfile(pubkey) {
    if (!this.options.getUserInfo) {
      console.log('FloatingTab: getUserInfo disabled, skipping profile fetch');
      return null;
    }

    // Determine which relays to use
    const relays = this.options.getUserRelay.length > 0
      ? this.options.getUserRelay
      : ['wss://relay.damus.io', 'wss://nos.lol'];

    console.log('FloatingTab: Fetching profile from relays:', relays);

    try {
      // Create a SimplePool instance for querying
      const pool = new window.NostrTools.SimplePool();
      
      // Query for kind 0 (user metadata) events
      const events = await pool.querySync(relays, {
        kinds: [0],
        authors: [pubkey],
        limit: 1
      }, { timeout: 5000 });

      console.log('FloatingTab: Profile query returned', events.length, 'events');

      if (events.length === 0) {
        console.log('FloatingTab: No profile events found');
        return null;
      }

      // Get the most recent event
      const latestEvent = events.sort((a, b) => b.created_at - a.created_at)[0];
      
      try {
        const profile = JSON.parse(latestEvent.content);
        console.log('FloatingTab: Parsed profile:', profile);
        
        // Find the best name from any key containing "name" (case-insensitive)
        let bestName = null;
        const nameKeys = Object.keys(profile).filter(key =>
          key.toLowerCase().includes('name') &&
          typeof profile[key] === 'string' &&
          profile[key].trim().length > 0
        );
        
        if (nameKeys.length > 0) {
          // Find the shortest name value
          bestName = nameKeys
            .map(key => profile[key].trim())
            .reduce((shortest, current) =>
              current.length < shortest.length ? current : shortest
            );
          console.log('FloatingTab: Found name keys:', nameKeys, 'selected:', bestName);
        }
        
        // Return relevant profile fields with the best name
        return {
          name: bestName,
          display_name: profile.display_name || null,
          about: profile.about || null,
          picture: profile.picture || null,
          nip05: profile.nip05 || null
        };
      } catch (parseError) {
        console.warn('FloatingTab: Failed to parse profile JSON:', parseError);
        return null;
      }
    } catch (error) {
      console.error('FloatingTab: Profile fetch error:', error);
      return null;
    }
  }

  _position() {
    if (!this.container) return;

    const padding = 16; // Distance from screen edge
    
    // Calculate position based on percentage
    const x = this.options.hPosition * (window.innerWidth - this.container.offsetWidth - padding * 2) + padding + this.options.offset.x;
    const y = this.options.vPosition * (window.innerHeight - this.container.offsetHeight - padding * 2) + padding + this.options.offset.y;
    
    this.container.style.left = `${x}px`;
    this.container.style.top = `${y}px`;

    console.log(`FloatingTab: Positioned at (${x}, ${y})`);
  }

  _slideIn() {
    if (!this.container || !this.options.behavior.autoSlide) return;
    
    // Slide towards center slightly
    const currentTransform = this.container.style.transform || '';
    if (this.options.hPosition > 0.5) {
      this.container.style.transform = currentTransform + ' translateX(-8px)';
    } else {
      this.container.style.transform = currentTransform + ' translateX(8px)';
    }
  }

  _slideOut() {
    if (!this.container || !this.options.behavior.autoSlide) return;
    
    // Reset position
    this.container.style.transform = '';
  }

  show() {
    if (!this.container) return;
    this.container.style.display = 'flex';
    this.isVisible = true;
    console.log('FloatingTab: Shown');
  }

  hide() {
    if (!this.container) return;
    this.container.style.display = 'none';
    this.isVisible = false;
    console.log('FloatingTab: Hidden');
  }

  destroy() {
    if (this.container) {
      this.container.remove();
      this.container = null;
    }
    this.isVisible = false;
    console.log('FloatingTab: Destroyed');
  }

  // Update options and re-apply
  updateOptions(newOptions) {
    this.options = { ...this.options, ...newOptions };
    if (this.container) {
      this._updateAppearance();
      this._position();
    }
  }

  // Get current state
  getState() {
    const authState = this._getAuthState();
    return {
      isVisible: this.isVisible,
      isAuthenticated: !!authState,
      userInfo: authState,
      options: this.options
    };
  }
}

// ======================================
// Main NOSTR_LOGIN_LITE Library
// ======================================

// Extension Bridge for managing browser extensions
class ExtensionBridge {
  constructor() {
    this.extensions = new Map();
    this.primaryExtension = null;
    this._detectExtensions();
  }
  
  _detectExtensions() {
    // Common extension locations
    const locations = [
      { path: 'window.nostr', name: 'Generic' },
      { path: 'window.alby?.nostr', name: 'Alby' },
      { path: 'window.nos2x?.nostr', name: 'nos2x' },
      { path: 'window.flamingo?.nostr', name: 'Flamingo' },
      { path: 'window.getAlby?.nostr', name: 'Alby Legacy' },
      { path: 'window.mutiny?.nostr', name: 'Mutiny' }
    ];
    
    for (const location of locations) {
      try {
        const obj = eval(location.path);
        if (obj && typeof obj.getPublicKey === 'function') {
          this.extensions.set(location.name, {
            name: location.name,
            extension: obj,
            constructor: obj.constructor?.name || 'Unknown'
          });
          
          if (!this.primaryExtension) {
            this.primaryExtension = this.extensions.get(location.name);
          }
        }
      } catch (e) {
        // Extension not available
      }
    }
  }
  
  getAllExtensions() {
    return Array.from(this.extensions.values());
  }
  
  getExtensionCount() {
    return this.extensions.size;
  }
}

// Main NostrLite class
class NostrLite {
  constructor() {
    this.options = {};
    this.extensionBridge = new ExtensionBridge();
    this.initialized = false;
    this.currentTheme = 'default';
    this.modal = null;
    this.floatingTab = null;
  }
  
  async init(options = {}) {
    console.log('NOSTR_LOGIN_LITE: Initializing with options:', options);
    
    this.options = {
      theme: 'default',
      persistence: true, // Enable persistent authentication by default
      isolateSession: false, // Use localStorage by default for cross-window persistence
      methods: {
        extension: true,
        local: true,
        seedphrase: false,
        readonly: true,
        connect: false,
        otp: false
      },
      floatingTab: {
        enabled: false,
        hPosition: 1.0,
        vPosition: 0.5,
        offset: { x: 0, y: 0 },
        appearance: {
          style: 'pill',
          theme: 'auto',
          icon: '',
          text: 'Login',
          iconOnly: false
        },
        behavior: {
          hideWhenAuthenticated: true,
          showUserInfo: true,
          autoSlide: true,
          persistent: false
        },
        getUserInfo: false,
        getUserRelay: []
      },
      ...options
    };
    
    // Apply the selected theme (CSS-only)
    this.switchTheme(this.options.theme);
    
    // Always set up window.nostr facade to handle multiple extensions properly
    console.log('🔍 NOSTR_LOGIN_LITE: Setting up facade before other initialization...');
    await this._setupWindowNostrFacade();
    console.log('🔍 NOSTR_LOGIN_LITE: Facade setup complete, continuing initialization...');
    
    // Create modal during init (matching original git architecture)
    this.modal = new Modal(this.options);
    console.log('NOSTR_LOGIN_LITE: Modal created during init');
    
    // Initialize floating tab if enabled
    if (this.options.floatingTab.enabled) {
      this.floatingTab = new FloatingTab(this.modal, this.options.floatingTab);
      console.log('NOSTR_LOGIN_LITE: Floating tab initialized');
    }
    
    // Attempt to restore authentication state if persistence is enabled (AFTER facade is ready)
    if (this.options.persistence) {
      console.log('🔍 NOSTR_LOGIN_LITE: Persistence enabled, attempting auth restoration...');
      await this._attemptAuthRestore();
    } else {
      console.log('🔍 NOSTR_LOGIN_LITE: Persistence disabled in options');
    }
    
    this.initialized = true;
    console.log('NOSTR_LOGIN_LITE: Initialization complete');
    
    return this;
  }
  
  async _setupWindowNostrFacade() {
    if (typeof window !== 'undefined') {
      console.log('🔍 NOSTR_LOGIN_LITE: === EXTENSION-FIRST FACADE SETUP ===');
      console.log('🔍 NOSTR_LOGIN_LITE: Current window.nostr:', window.nostr);
      console.log('🔍 NOSTR_LOGIN_LITE: Constructor:', window.nostr?.constructor?.name);
      
      // EXTENSION-FIRST ARCHITECTURE: Never interfere with real extensions
      if (this._isRealExtension(window.nostr)) {
        console.log('🔍 NOSTR_LOGIN_LITE: ✅ REAL EXTENSION DETECTED - WILL NOT INSTALL FACADE');
        console.log('🔍 NOSTR_LOGIN_LITE: Extension constructor:', window.nostr.constructor?.name);
        console.log('🔍 NOSTR_LOGIN_LITE: Extensions will handle window.nostr directly');
        
        // Store reference for persistence verification
        this.detectedExtension = window.nostr;
        this.hasExtension = true;
        this.facadeInstalled = false; // We deliberately don't install facade for extensions
        
        console.log('🔍 NOSTR_LOGIN_LITE: Extension mode - no facade interference');
        return; // Don't install facade at all for extensions
      }
      
      // NO EXTENSION: Install facade for local/NIP-46/readonly methods
      console.log('🔍 NOSTR_LOGIN_LITE: ❌ No real extension detected');
      console.log('🔍 NOSTR_LOGIN_LITE: Installing facade for non-extension authentication');
      
      this.hasExtension = false;
      this._installFacade(window.nostr); // Install facade with any existing nostr object
      
      console.log('🔍 NOSTR_LOGIN_LITE: ✅ Facade installed for local/NIP-46/readonly methods');
    }
  }
  
  _installFacade(existingNostr = null) {
    if (typeof window !== 'undefined' && !this.facadeInstalled) {
      console.log('🔍 NOSTR_LOGIN_LITE: === _installFacade CALLED ===');
      console.log('🔍 NOSTR_LOGIN_LITE: existingNostr parameter:', existingNostr);
      console.log('🔍 NOSTR_LOGIN_LITE: existingNostr constructor:', existingNostr?.constructor?.name);
      console.log('🔍 NOSTR_LOGIN_LITE: window.nostr before installation:', window.nostr);
      console.log('🔍 NOSTR_LOGIN_LITE: window.nostr constructor before:', window.nostr?.constructor?.name);
      
      const facade = new WindowNostr(this, existingNostr, { isolateSession: this.options.isolateSession });
      window.nostr = facade;
      this.facadeInstalled = true;
      
      console.log('🔍 NOSTR_LOGIN_LITE: === FACADE INSTALLED FOR PERSISTENCE ===');
      console.log('🔍 NOSTR_LOGIN_LITE: window.nostr after installation:', window.nostr);
      console.log('🔍 NOSTR_LOGIN_LITE: window.nostr constructor after:', window.nostr.constructor?.name);
      console.log('🔍 NOSTR_LOGIN_LITE: facade.existingNostr:', window.nostr.existingNostr);
    }
  }
  
  // Conservative method to identify real browser extensions
  _isRealExtension(obj) {
    console.log('NOSTR_LOGIN_LITE: === _isRealExtension (Conservative) ===');
    console.log('NOSTR_LOGIN_LITE: obj:', obj);
    console.log('NOSTR_LOGIN_LITE: typeof obj:', typeof obj);
    
    if (!obj || typeof obj !== 'object') {
      console.log('NOSTR_LOGIN_LITE: ✗ Not an object');
      return false;
    }
    
    // Must have required Nostr methods
    if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') {
      console.log('NOSTR_LOGIN_LITE: ✗ Missing required NIP-07 methods');
      return false;
    }

    // Exclude our own library classes
    const constructorName = obj.constructor?.name;
    console.log('NOSTR_LOGIN_LITE: Constructor name:', constructorName);
    
    if (constructorName === 'WindowNostr' || constructorName === 'NostrLite') {
      console.log('NOSTR_LOGIN_LITE: ✗ Is our library class - NOT an extension');
      return false;
    }

    // Exclude NostrTools library object
    if (obj === window.NostrTools) {
      console.log('NOSTR_LOGIN_LITE: ✗ Is NostrTools object - NOT an extension');
      return false;
    }

    // Conservative check: Look for common extension characteristics
    // Real extensions usually have some of these internal properties
    const extensionIndicators = [
      '_isEnabled', 'enabled', 'kind', '_eventEmitter', '_scope',
      '_requests', '_pubkey', 'name', 'version', 'description'
    ];
    
    const hasIndicators = extensionIndicators.some(prop => obj.hasOwnProperty(prop));
    
    // Additional check: Extensions often have specific constructor patterns
    const hasExtensionConstructor = constructorName &&
                                  constructorName !== 'Object' &&
                                  constructorName !== 'Function';

    const isExtension = hasIndicators || hasExtensionConstructor;
    
    console.log('NOSTR_LOGIN_LITE: Extension indicators found:', hasIndicators);
    console.log('NOSTR_LOGIN_LITE: Has extension constructor:', hasExtensionConstructor);
    console.log('NOSTR_LOGIN_LITE: Final result for', constructorName, ':', isExtension);
    
    return isExtension;
  }
  
  launch(startScreen = 'login') {
    console.log('NOSTR_LOGIN_LITE: Launching with screen:', startScreen);
    
    if (this.modal) {
      this.modal.open({ startScreen });
    } else {
      console.error('NOSTR_LOGIN_LITE: Modal not initialized - call init() first');
    }
  }
  
  // Attempt to restore authentication state
  async _attemptAuthRestore() {
    try {
      console.log('🔍 NOSTR_LOGIN_LITE: === _attemptAuthRestore START ===');
      console.log('🔍 NOSTR_LOGIN_LITE: hasExtension:', this.hasExtension);
      console.log('🔍 NOSTR_LOGIN_LITE: facadeInstalled:', this.facadeInstalled);
      console.log('🔍 NOSTR_LOGIN_LITE: window.nostr:', window.nostr?.constructor?.name);
      
      if (this.hasExtension) {
        // EXTENSION MODE: Use custom extension persistence logic
        console.log('🔍 NOSTR_LOGIN_LITE: Extension mode - using extension-specific restore');
        const restoredAuth = await this._attemptExtensionRestore();
        
        if (restoredAuth) {
          console.log('🔍 NOSTR_LOGIN_LITE: ✅ Extension auth restored successfully!');
          return restoredAuth;
        } else {
          console.log('🔍 NOSTR_LOGIN_LITE: ❌ Extension auth could not be restored');
          return null;
        }
      } else if (this.facadeInstalled && window.nostr?.restoreAuthState) {
        // NON-EXTENSION MODE: Use facade persistence logic
        console.log('🔍 NOSTR_LOGIN_LITE: Non-extension mode - using facade restore');
        const restoredAuth = await window.nostr.restoreAuthState();
        
        if (restoredAuth) {
          console.log('🔍 NOSTR_LOGIN_LITE: ✅ Facade auth restored successfully!');
          console.log('🔍 NOSTR_LOGIN_LITE: Method:', restoredAuth.method);
          console.log('🔍 NOSTR_LOGIN_LITE: Pubkey:', restoredAuth.pubkey);
          
          // Handle NIP-46 reconnection requirement
          if (restoredAuth.requiresReconnection) {
            console.log('🔍 NOSTR_LOGIN_LITE: NIP-46 connection requires user reconnection');
            this._showReconnectionPrompt(restoredAuth);
          }
          
          return restoredAuth;
        } else {
          console.log('🔍 NOSTR_LOGIN_LITE: ❌ Facade auth could not be restored');
          return null;
        }
      } else {
        console.log('🔍 NOSTR_LOGIN_LITE: ❌ No restoration method available');
        console.log('🔍 NOSTR_LOGIN_LITE: hasExtension:', this.hasExtension);
        console.log('🔍 NOSTR_LOGIN_LITE: facadeInstalled:', this.facadeInstalled);
        console.log('🔍 NOSTR_LOGIN_LITE: window.nostr.restoreAuthState:', typeof window.nostr?.restoreAuthState);
        return null;
      }
      
    } catch (error) {
      console.error('🔍 NOSTR_LOGIN_LITE: Auth restoration failed with error:', error);
      console.error('🔍 NOSTR_LOGIN_LITE: Error stack:', error.stack);
      return null;
    }
  }

  // Extension-specific authentication restoration
  async _attemptExtensionRestore() {
    try {
      console.log('🔍 NOSTR_LOGIN_LITE: === _attemptExtensionRestore START ===');
      
      // Use a simple AuthManager instance for extension persistence
      const authManager = new AuthManager({ isolateSession: this.options?.isolateSession });
      const storedAuth = await authManager.restoreAuthState();
      
      if (!storedAuth || storedAuth.method !== 'extension') {
        console.log('🔍 NOSTR_LOGIN_LITE: No extension auth state stored');
        return null;
      }
      
      // Verify the extension is still available and working
      if (!window.nostr || !this._isRealExtension(window.nostr)) {
        console.log('🔍 NOSTR_LOGIN_LITE: Extension no longer available');
        authManager.clearAuthState(); // Clear invalid state
        return null;
      }
      
      try {
        // Test that the extension still works with the same pubkey
        const currentPubkey = await window.nostr.getPublicKey();
        if (currentPubkey !== storedAuth.pubkey) {
          console.log('🔍 NOSTR_LOGIN_LITE: Extension pubkey changed, clearing state');
          authManager.clearAuthState();
          return null;
        }
        
        console.log('🔍 NOSTR_LOGIN_LITE: ✅ Extension auth verification successful');
        
        // Create extension auth data for UI restoration
        const extensionAuth = {
          method: 'extension',
          pubkey: storedAuth.pubkey,
          extension: window.nostr
        };
        
        // Dispatch restoration event so UI can update
        if (typeof window !== 'undefined') {
          console.log('🔍 NOSTR_LOGIN_LITE: Dispatching nlAuthRestored event for extension');
          window.dispatchEvent(new CustomEvent('nlAuthRestored', {
            detail: extensionAuth
          }));
        }
        
        return extensionAuth;
        
      } catch (error) {
        console.log('🔍 NOSTR_LOGIN_LITE: Extension verification failed:', error);
        authManager.clearAuthState(); // Clear invalid state
        return null;
      }
      
    } catch (error) {
      console.error('🔍 NOSTR_LOGIN_LITE: Extension restore failed:', error);
      return null;
    }
  }

  // Show prompt for NIP-46 reconnection
  _showReconnectionPrompt(authData) {
    console.log('NOSTR_LOGIN_LITE: Showing reconnection prompt for NIP-46');
    
    // Dispatch event that UI can listen to
    if (typeof window !== 'undefined') {
      window.dispatchEvent(new CustomEvent('nlReconnectionRequired', {
        detail: {
          method: authData.method,
          pubkey: authData.pubkey,
          connectionData: authData.connectionData,
          message: 'Your NIP-46 session has expired. Please reconnect to continue.'
        }
      }));
    }
  }

  logout() {
    console.log('NOSTR_LOGIN_LITE: Logout called');
    
    // Clear legacy stored data
    if (typeof localStorage !== 'undefined') {
      localStorage.removeItem('nl_current');
    }
    
    // Clear current authentication state directly from storage
    // This works for ALL methods including extensions (fixes the bug)
    clearAuthState();
    
    // Dispatch logout event for UI updates
    if (typeof window !== 'undefined') {
      window.dispatchEvent(new CustomEvent('nlLogout', {
        detail: { timestamp: Date.now() }
      }));
    }
  }
  
  // CSS-only theme switching
  switchTheme(themeName) {
    console.log(`NOSTR_LOGIN_LITE: Switching to ${themeName} theme`);
    
    if (THEME_CSS[themeName]) {
      injectThemeCSS(themeName);
      this.currentTheme = themeName;
      
      // Dispatch theme change event
      if (typeof window !== 'undefined') {
        window.dispatchEvent(new CustomEvent('nlThemeChanged', {
          detail: { theme: themeName }
        }));
      }
      
      return { theme: themeName };
    } else {
      console.warn(`Theme '${themeName}' not found, using default`);
      injectThemeCSS('default');
      this.currentTheme = 'default';
      return { theme: 'default' };
    }
  }
  
  getCurrentTheme() {
    return this.currentTheme;
  }
  
  getAvailableThemes() {
    return Object.keys(THEME_CSS);
  }
  
  embed(container, options = {}) {
    console.log('NOSTR_LOGIN_LITE: Creating embedded modal in container:', container);
    
    const embedOptions = {
      ...this.options,
      ...options,
      embedded: container
    };
    
    // Create new modal instance for embedding
    const embeddedModal = new Modal(embedOptions);
    embeddedModal.open();
    
    return embeddedModal;
  }

  // Floating tab management methods
  showFloatingTab() {
    if (this.floatingTab) {
      this.floatingTab.show();
    } else {
      console.warn('NOSTR_LOGIN_LITE: Floating tab not enabled');
    }
  }

  hideFloatingTab() {
    if (this.floatingTab) {
      this.floatingTab.hide();
    }
  }

  toggleFloatingTab() {
    if (this.floatingTab) {
      if (this.floatingTab.isVisible) {
        this.floatingTab.hide();
      } else {
        this.floatingTab.show();
      }
    }
  }

  updateFloatingTab(options) {
    if (this.floatingTab) {
      this.floatingTab.updateOptions(options);
    }
  }

  getFloatingTabState() {
    return this.floatingTab ? this.floatingTab.getState() : null;
  }
}

// ======================================
// Authentication Manager for Persistent Login
// ======================================

// Encryption utilities for secure local storage
class CryptoUtils {
  static async generateKey() {
    if (!window.crypto?.subtle) {
      throw new Error('Web Crypto API not available');
    }
    
    return await window.crypto.subtle.generateKey(
      {
        name: 'AES-GCM',
        length: 256,
      },
      true,
      ['encrypt', 'decrypt']
    );
  }

  static async deriveKey(password, salt) {
    if (!window.crypto?.subtle) {
      throw new Error('Web Crypto API not available');
    }
    
    const encoder = new TextEncoder();
    const keyMaterial = await window.crypto.subtle.importKey(
      'raw',
      encoder.encode(password),
      { name: 'PBKDF2' },
      false,
      ['deriveBits', 'deriveKey']
    );
    
    return await window.crypto.subtle.deriveKey(
      {
        name: 'PBKDF2',
        salt: salt,
        iterations: 100000,
        hash: 'SHA-256',
      },
      keyMaterial,
      { name: 'AES-GCM', length: 256 },
      true,
      ['encrypt', 'decrypt']
    );
  }

  static async encrypt(data, key) {
    if (!window.crypto?.subtle) {
      throw new Error('Web Crypto API not available');
    }
    
    const encoder = new TextEncoder();
    const iv = window.crypto.getRandomValues(new Uint8Array(12));
    
    const encrypted = await window.crypto.subtle.encrypt(
      {
        name: 'AES-GCM',
        iv: iv,
      },
      key,
      encoder.encode(data)
    );
    
    return {
      encrypted: new Uint8Array(encrypted),
      iv: iv
    };
  }

  static async decrypt(encryptedData, key, iv) {
    if (!window.crypto?.subtle) {
      throw new Error('Web Crypto API not available');
    }
    
    const decrypted = await window.crypto.subtle.decrypt(
      {
        name: 'AES-GCM',
        iv: iv,
      },
      key,
      encryptedData
    );
    
    const decoder = new TextDecoder();
    return decoder.decode(decrypted);
  }

  static arrayBufferToBase64(buffer) {
    const bytes = new Uint8Array(buffer);
    let binary = '';
    for (let i = 0; i < bytes.byteLength; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
  }

  static base64ToArrayBuffer(base64) {
    const binary = window.atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
      bytes[i] = binary.charCodeAt(i);
    }
    return bytes.buffer;
  }
}

// Unified authentication state manager
class AuthManager {
  constructor(options = {}) {
    this.storageKey = 'nostr_login_lite_auth';
    this.currentAuthState = null;
    
    // Configure storage type based on isolateSession option
    if (options.isolateSession) {
      this.storage = sessionStorage;
      console.log('AuthManager: Using sessionStorage for per-window isolation');
    } else {
      this.storage = localStorage;
      console.log('AuthManager: Using localStorage for cross-window persistence');
    }
  }

  // Save authentication state with method-specific security
  async saveAuthState(authData) {
    try {
      const authState = {
        method: authData.method,
        timestamp: Date.now(),
        pubkey: authData.pubkey
      };

      switch (authData.method) {
        case 'extension':
          // For extensions, only store verification data - no secrets
          authState.extensionVerification = {
            constructor: authData.extension?.constructor?.name,
            hasGetPublicKey: typeof authData.extension?.getPublicKey === 'function',
            hasSignEvent: typeof authData.extension?.signEvent === 'function'
          };
          break;

        case 'local':
          // For local keys, encrypt the secret key
          if (authData.secret) {
            const password = this._generateSessionPassword();
            const salt = window.crypto.getRandomValues(new Uint8Array(16));
            const key = await CryptoUtils.deriveKey(password, salt);
            const encrypted = await CryptoUtils.encrypt(authData.secret, key);
            
            authState.encrypted = {
              data: CryptoUtils.arrayBufferToBase64(encrypted.encrypted),
              iv: CryptoUtils.arrayBufferToBase64(encrypted.iv),
              salt: CryptoUtils.arrayBufferToBase64(salt)
            };
            
            // Store session password in sessionStorage (cleared on tab close)
            sessionStorage.setItem('nostr_session_key', password);
          }
          break;

        case 'nip46':
          // For NIP-46, store connection parameters (no secrets)
          if (authData.signer) {
            authState.nip46 = {
              remotePubkey: authData.signer.remotePubkey,
              relays: authData.signer.relays,
              // Don't store secret - user will need to reconnect
            };
          }
          break;

        case 'readonly':
          // Read-only mode has no secrets to store
          break;

        default:
          throw new Error(`Unknown auth method: ${authData.method}`);
      }

      this.storage.setItem(this.storageKey, JSON.stringify(authState));
      this.currentAuthState = authState;
      console.log('AuthManager: Auth state saved for method:', authData.method);
      
    } catch (error) {
      console.error('AuthManager: Failed to save auth state:', error);
      throw error;
    }
  }

  // Restore authentication state on page load
  async restoreAuthState() {
    try {
      console.log('🔍 AuthManager: === restoreAuthState START ===');
      console.log('🔍 AuthManager: storageKey:', this.storageKey);
      
      const stored = this.storage.getItem(this.storageKey);
      console.log('🔍 AuthManager: localStorage raw value:', stored);
      
      if (!stored) {
        console.log('🔍 AuthManager: ❌ No stored auth state found');
        return null;
      }

      const authState = JSON.parse(stored);
      console.log('🔍 AuthManager: ✅ Parsed stored auth state:', authState);
      console.log('🔍 AuthManager: Method:', authState.method);
      console.log('🔍 AuthManager: Timestamp:', authState.timestamp);
      console.log('🔍 AuthManager: Age (ms):', Date.now() - authState.timestamp);

      // Check if stored state is too old (24 hours for most methods, 1 hour for extensions)
      const maxAge = authState.method === 'extension' ? 60 * 60 * 1000 : 24 * 60 * 60 * 1000;
      console.log('🔍 AuthManager: Max age for method:', maxAge, 'ms');
      
      if (Date.now() - authState.timestamp > maxAge) {
        console.log('🔍 AuthManager: ❌ Stored auth state expired, clearing');
        this.clearAuthState();
        return null;
      }

      console.log('🔍 AuthManager: ✅ Auth state not expired, attempting restore for method:', authState.method);

      let result;
      switch (authState.method) {
        case 'extension':
          console.log('🔍 AuthManager: Calling _restoreExtensionAuth...');
          result = await this._restoreExtensionAuth(authState);
          break;

        case 'local':
          console.log('🔍 AuthManager: Calling _restoreLocalAuth...');
          result = await this._restoreLocalAuth(authState);
          break;

        case 'nip46':
          console.log('🔍 AuthManager: Calling _restoreNip46Auth...');
          result = await this._restoreNip46Auth(authState);
          break;

        case 'readonly':
          console.log('🔍 AuthManager: Calling _restoreReadonlyAuth...');
          result = await this._restoreReadonlyAuth(authState);
          break;

        default:
          console.warn('🔍 AuthManager: ❌ Unknown auth method in stored state:', authState.method);
          return null;
      }

      console.log('🔍 AuthManager: Restore method result:', result);
      console.log('🔍 AuthManager: === restoreAuthState END ===');
      return result;

    } catch (error) {
      console.error('🔍 AuthManager: ❌ Failed to restore auth state:', error);
      console.error('🔍 AuthManager: Error stack:', error.stack);
      this.clearAuthState(); // Clear corrupted state
      return null;
    }
  }

  async _restoreExtensionAuth(authState) {
    console.log('🔍 AuthManager: === _restoreExtensionAuth START ===');
    console.log('🔍 AuthManager: authState:', authState);
    console.log('🔍 AuthManager: window.nostr available:', !!window.nostr);
    console.log('🔍 AuthManager: window.nostr constructor:', window.nostr?.constructor?.name);

    // SMART EXTENSION WAITING SYSTEM
    // Extensions often load after our library, so we need to wait for them
    const extension = await this._waitForExtension(authState, 3000); // Wait up to 3 seconds
    
    if (!extension) {
      console.log('🔍 AuthManager: ❌ No extension found after waiting');
      return null;
    }

    console.log('🔍 AuthManager: ✅ Extension found:', extension.constructor?.name);

    try {
      // Verify extension still works and has same pubkey
      const currentPubkey = await extension.getPublicKey();
      if (currentPubkey !== authState.pubkey) {
        console.log('🔍 AuthManager: ❌ Extension pubkey changed, not restoring');
        console.log('🔍 AuthManager: Expected:', authState.pubkey);
        console.log('🔍 AuthManager: Got:', currentPubkey);
        return null;
      }

      console.log('🔍 AuthManager: ✅ Extension auth restored successfully');
      return {
        method: 'extension',
        pubkey: authState.pubkey,
        extension: extension
      };

    } catch (error) {
      console.log('🔍 AuthManager: ❌ Extension verification failed:', error);
      return null;
    }
  }

  // Smart extension waiting system - polls multiple locations for extensions
  async _waitForExtension(authState, maxWaitMs = 3000) {
    console.log('🔍 AuthManager: === _waitForExtension START ===');
    console.log('🔍 AuthManager: maxWaitMs:', maxWaitMs);
    console.log('🔍 AuthManager: Looking for extension with constructor:', authState.extensionVerification?.constructor);

    const startTime = Date.now();
    const pollInterval = 100; // Check every 100ms
    
    // Extension locations to check (in priority order)
    const extensionLocations = [
      { path: 'window.nostr', getter: () => window.nostr },
      { path: 'navigator.nostr', getter: () => navigator?.nostr },
      { path: 'window.navigator?.nostr', getter: () => window.navigator?.nostr },
      { path: 'window.alby?.nostr', getter: () => window.alby?.nostr },
      { path: 'window.webln?.nostr', getter: () => window.webln?.nostr },
      { path: 'window.nos2x', getter: () => window.nos2x },
      { path: 'window.flamingo?.nostr', getter: () => window.flamingo?.nostr },
      { path: 'window.mutiny?.nostr', getter: () => window.mutiny?.nostr }
    ];

    while (Date.now() - startTime < maxWaitMs) {
      console.log('🔍 AuthManager: Polling for extensions... (elapsed:', Date.now() - startTime, 'ms)');

      // If our facade is currently installed and blocking, temporarily remove it
      let facadeRemoved = false;
      let originalNostr = null;
      if (window.nostr?.constructor?.name === 'WindowNostr') {
        console.log('🔍 AuthManager: Temporarily removing our facade to check for real extensions');
        originalNostr = window.nostr;
        window.nostr = window.nostr.existingNostr || undefined;
        facadeRemoved = true;
      }

      try {
        // Check all extension locations
        for (const location of extensionLocations) {
          try {
            const extension = location.getter();
            console.log('🔍 AuthManager: Checking', location.path, ':', !!extension, extension?.constructor?.name);

            if (this._isValidExtensionForRestore(extension, authState)) {
              console.log('🔍 AuthManager: ✅ Found matching extension at', location.path);
              
              // Restore facade if we removed it
              if (facadeRemoved && originalNostr) {
                console.log('🔍 AuthManager: Restoring facade after finding extension');
                window.nostr = originalNostr;
              }
              
              return extension;
            }
          } catch (error) {
            console.log('🔍 AuthManager: Error checking', location.path, ':', error.message);
          }
        }

        // Restore facade if we removed it and haven't found an extension yet
        if (facadeRemoved && originalNostr) {
          window.nostr = originalNostr;
          facadeRemoved = false;
        }

      } catch (error) {
        console.error('🔍 AuthManager: Error during extension polling:', error);
        
        // Restore facade if we removed it
        if (facadeRemoved && originalNostr) {
          window.nostr = originalNostr;
        }
      }

      // Wait before next poll
      await new Promise(resolve => setTimeout(resolve, pollInterval));
    }

    console.log('🔍 AuthManager: ❌ Extension waiting timeout after', maxWaitMs, 'ms');
    return null;
  }

  // Check if an extension is valid for restoration
  _isValidExtensionForRestore(extension, authState) {
    if (!extension || typeof extension !== 'object') {
      return false;
    }

    // Must have required Nostr methods
    if (typeof extension.getPublicKey !== 'function' ||
        typeof extension.signEvent !== 'function') {
      return false;
    }

    // Must not be our own classes
    const constructorName = extension.constructor?.name;
    if (constructorName === 'WindowNostr' || constructorName === 'NostrLite') {
      return false;
    }

    // Must not be NostrTools
    if (extension === window.NostrTools) {
      return false;
    }

    // If we have stored verification data, check constructor match
    const verification = authState.extensionVerification;
    if (verification && verification.constructor) {
      if (constructorName !== verification.constructor) {
        console.log('🔍 AuthManager: Constructor mismatch -',
                   'expected:', verification.constructor,
                   'got:', constructorName);
        return false;
      }
    }

    console.log('🔍 AuthManager: ✅ Extension validation passed for:', constructorName);
    return true;
  }

  async _restoreLocalAuth(authState) {
    if (!authState.encrypted) {
      console.log('AuthManager: No encrypted data found for local auth');
      return null;
    }

    // Get session password
    const sessionPassword = sessionStorage.getItem('nostr_session_key');
    if (!sessionPassword) {
      console.log('AuthManager: Session password not found, cannot decrypt');
      return null;
    }

    try {
      // Decrypt the secret key
      const salt = CryptoUtils.base64ToArrayBuffer(authState.encrypted.salt);
      const key = await CryptoUtils.deriveKey(sessionPassword, new Uint8Array(salt));
      
      const encryptedData = CryptoUtils.base64ToArrayBuffer(authState.encrypted.data);
      const iv = CryptoUtils.base64ToArrayBuffer(authState.encrypted.iv);
      
      const secret = await CryptoUtils.decrypt(encryptedData, key, new Uint8Array(iv));

      console.log('AuthManager: Local auth restored successfully');
      return {
        method: 'local',
        pubkey: authState.pubkey,
        secret: secret
      };

    } catch (error) {
      console.error('AuthManager: Failed to decrypt local key:', error);
      return null;
    }
  }

  async _restoreNip46Auth(authState) {
    if (!authState.nip46) {
      console.log('AuthManager: No NIP-46 data found');
      return null;
    }

    // For NIP-46, we can't automatically restore the connection
    // because it requires the user to re-authenticate with the remote signer
    // Instead, we return the connection parameters so the UI can prompt for reconnection
    console.log('AuthManager: NIP-46 connection data found, requires user reconnection');
    return {
      method: 'nip46',
      pubkey: authState.pubkey,
      requiresReconnection: true,
      connectionData: authState.nip46
    };
  }

  async _restoreReadonlyAuth(authState) {
    console.log('AuthManager: Read-only auth restored successfully');
    return {
      method: 'readonly',
      pubkey: authState.pubkey
    };
  }

  // Clear stored authentication state
  clearAuthState() {
    this.storage.removeItem(this.storageKey);
    sessionStorage.removeItem('nostr_session_key');
    this.currentAuthState = null;
    console.log('AuthManager: Auth state cleared');
  }

  // Generate a session-specific password for local key encryption
  _generateSessionPassword() {
    const array = new Uint8Array(32);
    window.crypto.getRandomValues(array);
    return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
  }

  // Check if we have valid stored auth
  hasStoredAuth() {
    const stored = this.storage.getItem(this.storageKey);
    return !!stored;
  }

  // Get current auth method without full restoration
  getStoredAuthMethod() {
    try {
      const stored = this.storage.getItem(this.storageKey);
      if (!stored) return null;
      
      const authState = JSON.parse(stored);
      return authState.method;
    } catch {
      return null;
    }
  }
}

// NIP-07 compliant window.nostr provider
class WindowNostr {
  constructor(nostrLite, existingNostr = null) {
    this.nostrLite = nostrLite;
    this.authState = null;
    this.existingNostr = existingNostr;
    this.authenticatedExtension = null;
    this.authManager = new AuthManager({ isolateSession: nostrLite.options?.isolateSession });
    this._setupEventListeners();
  }

  _setupEventListeners() {
    // Listen for authentication events to store auth state
    if (typeof window !== 'undefined') {
      window.addEventListener('nlMethodSelected', async (event) => {
        this.authState = event.detail;
        
        // If extension method, capture the specific extension the user chose
        if (event.detail.method === 'extension') {
          this.authenticatedExtension = event.detail.extension;
          console.log('WindowNostr: Captured authenticated extension:', this.authenticatedExtension?.constructor?.name);
        }
        
        // Use global setAuthState function for unified persistence
        try {
          setAuthState(event.detail, { isolateSession: this.nostrLite.options?.isolateSession });
          console.log('WindowNostr: Auth state saved via global setAuthState');
        } catch (error) {
          console.error('WindowNostr: Failed to save auth state via global setAuthState:', error);
        }
        
        // EXTENSION-FIRST: Only reinstall facade for non-extension methods
        // Extensions handle their own window.nostr - don't interfere!
        if (event.detail.method !== 'extension' && typeof window !== 'undefined') {
          console.log('WindowNostr: Re-installing facade after', this.authState?.method, 'authentication');
          window.nostr = this;
        } else if (event.detail.method === 'extension') {
          console.log('WindowNostr: Extension authentication - NOT reinstalling facade');
        }
        
        console.log('WindowNostr: Auth state updated:', this.authState?.method);
      });

      window.addEventListener('nlLogout', () => {
        this.authState = null;
        this.authenticatedExtension = null;
        
        // Clear persistent auth state
        this.authManager.clearAuthState();
        console.log('WindowNostr: Auth state cleared and persistence removed');
        
        // EXTENSION-FIRST: Only reinstall facade if we're not in extension mode
        if (typeof window !== 'undefined' && !this.nostrLite?.hasExtension) {
          console.log('WindowNostr: Re-installing facade after logout (non-extension mode)');
          window.nostr = this;
        } else {
          console.log('WindowNostr: Logout in extension mode - NOT reinstalling facade');
        }
      });
    }
  }

  // Restore authentication state on page load
  async restoreAuthState() {
    try {
      console.log('🔍 WindowNostr: === restoreAuthState START ===');
      console.log('🔍 WindowNostr: authManager available:', !!this.authManager);
      
      const restoredAuth = await this.authManager.restoreAuthState();
      console.log('🔍 WindowNostr: authManager.restoreAuthState result:', restoredAuth);
      
      if (restoredAuth) {
        console.log('🔍 WindowNostr: ✅ Setting authState to restored auth');
        this.authState = restoredAuth;
        console.log('🔍 WindowNostr: this.authState now:', this.authState);
        
        // Handle method-specific restoration
        if (restoredAuth.method === 'extension') {
          console.log('🔍 WindowNostr: Extension method - setting authenticatedExtension');
          this.authenticatedExtension = restoredAuth.extension;
          console.log('🔍 WindowNostr: authenticatedExtension set to:', this.authenticatedExtension);
        }
        
        console.log('🔍 WindowNostr: ✅ Authentication state restored successfully!');
        console.log('🔍 WindowNostr: Method:', restoredAuth.method);
        console.log('🔍 WindowNostr: Pubkey:', restoredAuth.pubkey);
        
        // Dispatch restoration event so UI can update
        if (typeof window !== 'undefined') {
          console.log('🔍 WindowNostr: Dispatching nlAuthRestored event...');
          const event = new CustomEvent('nlAuthRestored', {
            detail: restoredAuth
          });
          console.log('🔍 WindowNostr: Event detail:', event.detail);
          window.dispatchEvent(event);
          console.log('🔍 WindowNostr: ✅ nlAuthRestored event dispatched');
        }
        
        console.log('🔍 WindowNostr: === restoreAuthState END (success) ===');
        return restoredAuth;
      } else {
        console.log('🔍 WindowNostr: ❌ No authentication state to restore (null from authManager)');
        console.log('🔍 WindowNostr: === restoreAuthState END (no restore) ===');
        return null;
      }
    } catch (error) {
      console.error('🔍 WindowNostr: ❌ Failed to restore auth state:', error);
      console.error('🔍 WindowNostr: Error stack:', error.stack);
      console.log('🔍 WindowNostr: === restoreAuthState END (error) ===');
      return null;
    }
  }

  async getPublicKey() {
    if (!this.authState) {
      throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
    }

    switch (this.authState.method) {
      case 'extension':
        // Use the captured authenticated extension, not current window.nostr
        const ext = this.authenticatedExtension || this.authState.extension || this.existingNostr;
        if (!ext) throw new Error('Extension not available');
        return await ext.getPublicKey();
        
      case 'local':
      case 'nip46':
        return this.authState.pubkey;
        
      case 'readonly':
        throw new Error('Read-only mode - cannot get public key');
        
      default:
        throw new Error(`Unsupported auth method: ${this.authState.method}`);
    }
  }

  async signEvent(event) {
    if (!this.authState) {
      throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
    }

    if (this.authState.method === 'readonly') {
      throw new Error('Read-only mode - cannot sign events');
    }

    switch (this.authState.method) {
      case 'extension':
        // Use the captured authenticated extension, not current window.nostr
        console.log('WindowNostr: signEvent - authenticatedExtension:', this.authenticatedExtension);
        console.log('WindowNostr: signEvent - authState.extension:', this.authState.extension);
        console.log('WindowNostr: signEvent - existingNostr:', this.existingNostr);
        
        const ext = this.authenticatedExtension || this.authState.extension || this.existingNostr;
        console.log('WindowNostr: signEvent - using extension:', ext);
        console.log('WindowNostr: signEvent - extension constructor:', ext?.constructor?.name);
        
        if (!ext) throw new Error('Extension not available');
        return await ext.signEvent(event);
        
      case 'local': {
        // Use nostr-tools to sign with local secret key
        const { nip19, finalizeEvent } = window.NostrTools;
        let secretKey;
        
        if (this.authState.secret.startsWith('nsec')) {
          const decoded = nip19.decode(this.authState.secret);
          secretKey = decoded.data;
        } else {
          // Convert hex to Uint8Array
          secretKey = this._hexToUint8Array(this.authState.secret);
        }
        
        return finalizeEvent(event, secretKey);
      }
      
      case 'nip46': {
        // Use BunkerSigner for NIP-46
        if (!this.authState.signer?.bunkerSigner) {
          throw new Error('NIP-46 signer not available');
        }
        return await this.authState.signer.bunkerSigner.signEvent(event);
      }
      
      default:
        throw new Error(`Unsupported auth method: ${this.authState.method}`);
    }
  }

  async getRelays() {
    // Return default relays since we removed the relays configuration
    return ['wss://relay.damus.io', 'wss://nos.lol'];
  }

  get nip04() {
    return {
      encrypt: async (pubkey, plaintext) => {
        if (!this.authState) {
          throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
        }

        if (this.authState.method === 'readonly') {
          throw new Error('Read-only mode - cannot encrypt');
        }

        switch (this.authState.method) {
          case 'extension': {
            const ext = this.authenticatedExtension || this.authState.extension || this.existingNostr;
            if (!ext) throw new Error('Extension not available');
            return await ext.nip04.encrypt(pubkey, plaintext);
          }
            
          case 'local': {
            const { nip04, nip19 } = window.NostrTools;
            let secretKey;
            
            if (this.authState.secret.startsWith('nsec')) {
              const decoded = nip19.decode(this.authState.secret);
              secretKey = decoded.data;
            } else {
              secretKey = this._hexToUint8Array(this.authState.secret);
            }
            
            return await nip04.encrypt(secretKey, pubkey, plaintext);
          }
          
          case 'nip46': {
            if (!this.authState.signer?.bunkerSigner) {
              throw new Error('NIP-46 signer not available');
            }
            return await this.authState.signer.bunkerSigner.nip04Encrypt(pubkey, plaintext);
          }
          
          default:
            throw new Error(`Unsupported auth method: ${this.authState.method}`);
        }
      },

      decrypt: async (pubkey, ciphertext) => {
        if (!this.authState) {
          throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
        }

        if (this.authState.method === 'readonly') {
          throw new Error('Read-only mode - cannot decrypt');
        }

        switch (this.authState.method) {
          case 'extension': {
            const ext = this.authenticatedExtension || this.authState.extension || this.existingNostr;
            if (!ext) throw new Error('Extension not available');
            return await ext.nip04.decrypt(pubkey, ciphertext);
          }
            
          case 'local': {
            const { nip04, nip19 } = window.NostrTools;
            let secretKey;
            
            if (this.authState.secret.startsWith('nsec')) {
              const decoded = nip19.decode(this.authState.secret);
              secretKey = decoded.data;
            } else {
              secretKey = this._hexToUint8Array(this.authState.secret);
            }
            
            return await nip04.decrypt(secretKey, pubkey, ciphertext);
          }
          
          case 'nip46': {
            if (!this.authState.signer?.bunkerSigner) {
              throw new Error('NIP-46 signer not available');
            }
            return await this.authState.signer.bunkerSigner.nip04Decrypt(pubkey, ciphertext);
          }
          
          default:
            throw new Error(`Unsupported auth method: ${this.authState.method}`);
        }
      }
    };
  }

  get nip44() {
    return {
      encrypt: async (pubkey, plaintext) => {
        const authState = getAuthState();
        if (!authState) {
          throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
        }

        if (authState.method === 'readonly') {
          throw new Error('Read-only mode - cannot encrypt');
        }

        switch (authState.method) {
          case 'extension': {
            const ext = this.authenticatedExtension || authState.extension || this.existingNostr;
            if (!ext) throw new Error('Extension not available');
            return await ext.nip44.encrypt(pubkey, plaintext);
          }
            
          case 'local': {
            const { nip44, nip19 } = window.NostrTools;
            let secretKey;
            
            if (authState.secret.startsWith('nsec')) {
              const decoded = nip19.decode(authState.secret);
              secretKey = decoded.data;
            } else {
              secretKey = this._hexToUint8Array(authState.secret);
            }
            
            return nip44.encrypt(plaintext, nip44.getConversationKey(secretKey, pubkey));
          }
          
          case 'nip46': {
            if (!authState.signer?.bunkerSigner) {
              throw new Error('NIP-46 signer not available');
            }
            return await authState.signer.bunkerSigner.nip44Encrypt(pubkey, plaintext);
          }
          
          default:
            throw new Error('Unsupported auth method: ' + authState.method);
        }
      },

      decrypt: async (pubkey, ciphertext) => {
        const authState = getAuthState();
        if (!authState) {
          throw new Error('Not authenticated - use NOSTR_LOGIN_LITE.launch()');
        }

        if (authState.method === 'readonly') {
          throw new Error('Read-only mode - cannot decrypt');
        }

        switch (authState.method) {
          case 'extension': {
            const ext = this.authenticatedExtension || authState.extension || this.existingNostr;
            if (!ext) throw new Error('Extension not available');
            return await ext.nip44.decrypt(pubkey, ciphertext);
          }
            
          case 'local': {
            const { nip44, nip19 } = window.NostrTools;
            let secretKey;
            
            if (authState.secret.startsWith('nsec')) {
              const decoded = nip19.decode(authState.secret);
              secretKey = decoded.data;
            } else {
              secretKey = this._hexToUint8Array(authState.secret);
            }
            
            return nip44.decrypt(ciphertext, nip44.getConversationKey(secretKey, pubkey));
          }
          
          case 'nip46': {
            if (!authState.signer?.bunkerSigner) {
              throw new Error('NIP-46 signer not available');
            }
            return await authState.signer.bunkerSigner.nip44Decrypt(pubkey, ciphertext);
          }
          
          default:
            throw new Error('Unsupported auth method: ' + authState.method);
        }
      }
    };
  }

  _hexToUint8Array(hex) {
    if (hex.length % 2 !== 0) {
      throw new Error('Invalid hex string length');
    }
    const bytes = new Uint8Array(hex.length / 2);
    for (let i = 0; i < bytes.length; i++) {
      bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
    }
    return bytes;
  }
}

// ======================================
// Global Authentication State Manager - Single Source of Truth
// ======================================

// Storage-based authentication state - works regardless of extension presence
function getAuthState() {
  try {
    console.log('🔍 getAuthState: === GLOBAL AUTH STATE CHECK ===');
    
    const storageKey = 'nostr_login_lite_auth';
    let stored = null;
    let storageType = null;
    
    // Check sessionStorage first (per-window isolation), then localStorage
    if (sessionStorage.getItem(storageKey)) {
      stored = sessionStorage.getItem(storageKey);
      storageType = 'sessionStorage';
      console.log('🔍 getAuthState: Found auth in sessionStorage');
    } else if (localStorage.getItem(storageKey)) {
      stored = localStorage.getItem(storageKey);
      storageType = 'localStorage';
      console.log('🔍 getAuthState: Found auth in localStorage');
    }
    
    if (!stored) {
      console.log('🔍 getAuthState: ❌ No stored auth state found');
      return null;
    }
    
    const authState = JSON.parse(stored);
    console.log('🔍 getAuthState: ✅ Parsed stored auth state from', storageType);
    console.log('🔍 getAuthState: Method:', authState.method);
    console.log('🔍 getAuthState: Pubkey:', authState.pubkey);
    console.log('🔍 getAuthState: Age (ms):', Date.now() - authState.timestamp);
    
    // Check if auth state is expired
    const maxAge = authState.method === 'extension' ? 60 * 60 * 1000 : 24 * 60 * 60 * 1000;
    if (Date.now() - authState.timestamp > maxAge) {
      console.log('🔍 getAuthState: ❌ Auth state expired, clearing');
      sessionStorage.removeItem(storageKey);
      localStorage.removeItem(storageKey);
      return null;
    }
    
    console.log('🔍 getAuthState: ✅ Valid auth state found');
    return authState;
    
  } catch (error) {
    console.error('🔍 getAuthState: ❌ Error reading auth state:', error);
    return null;
  }
}

// ======================================
// Global Authentication State Management - Unified Persistence
// ======================================

// Global setAuthState function for unified persistence across all authentication methods
function setAuthState(authData, options = {}) {
  try {
    console.log('🔍 setAuthState: === GLOBAL AUTH STATE SAVE ===');
    console.log('🔍 setAuthState: authData:', authData);
    console.log('🔍 setAuthState: options:', options);
    
    const storageKey = 'nostr_login_lite_auth';
    
    // Determine which storage to use based on isolateSession option
    const storage = options.isolateSession ? sessionStorage : localStorage;
    const storageType = options.isolateSession ? 'sessionStorage' : 'localStorage';
    
    console.log('🔍 setAuthState: Using', storageType, 'for persistence');
    
    // Create auth state object
    const authState = {
      method: authData.method,
      timestamp: Date.now(),
      pubkey: authData.pubkey
    };
    
    // Add method-specific data (but no secrets for extension method)
    switch (authData.method) {
      case 'extension':
        // For extensions, only store verification data - no secrets
        authState.extensionVerification = {
          constructor: authData.extension?.constructor?.name,
          hasGetPublicKey: typeof authData.extension?.getPublicKey === 'function',
          hasSignEvent: typeof authData.extension?.signEvent === 'function'
        };
        console.log('🔍 setAuthState: Extension method - storing verification data only');
        break;
        
      case 'local':
        // For local keys, store the secret (will be encrypted by AuthManager if needed)
        if (authData.secret) {
          authState.secret = authData.secret;
          console.log('🔍 setAuthState: Local method - storing secret key');
        }
        break;
        
      case 'nip46':
        // For NIP-46, store connection parameters
        if (authData.signer) {
          authState.nip46 = {
            remotePubkey: authData.signer.remotePubkey,
            relays: authData.signer.relays,
            // Don't store secret - user will need to reconnect
          };
          console.log('🔍 setAuthState: NIP-46 method - storing connection parameters');
        }
        break;
        
      case 'readonly':
        // Read-only mode has no additional data to store
        console.log('🔍 setAuthState: Read-only method - storing basic auth state');
        break;
        
      default:
        console.warn('🔍 setAuthState: Unknown auth method:', authData.method);
        break;
    }
    
    // Store the auth state
    storage.setItem(storageKey, JSON.stringify(authState));
    console.log('🔍 setAuthState: ✅ Auth state saved successfully');
    console.log('🔍 setAuthState: Final auth state:', authState);
    
    return authState;
    
  } catch (error) {
    console.error('🔍 setAuthState: ❌ Error saving auth state:', error);
    throw error;
  }
}

// ======================================
// Global Authentication State Clearing
// ======================================

// Global clearAuthState function for unified auth state clearing
function clearAuthState() {
  try {
    console.log('🔍 clearAuthState: === GLOBAL AUTH STATE CLEAR ===');
    
    const storageKey = 'nostr_login_lite_auth';
    
    // Clear from both storage types to ensure complete cleanup
    if (typeof sessionStorage !== 'undefined') {
      sessionStorage.removeItem(storageKey);
      sessionStorage.removeItem('nostr_session_key');
      console.log('🔍 clearAuthState: ✅ Cleared auth state from sessionStorage');
    }
    
    if (typeof localStorage !== 'undefined') {
      localStorage.removeItem(storageKey);
      console.log('🔍 clearAuthState: ✅ Cleared auth state from localStorage');
    }
    
    console.log('🔍 clearAuthState: ✅ All auth state cleared successfully');
    
  } catch (error) {
    console.error('🔍 clearAuthState: ❌ Error clearing auth state:', error);
  }
}


// Initialize and export
if (typeof window !== 'undefined') {
  const nostrLite = new NostrLite();
  
  // Export main API
  window.NOSTR_LOGIN_LITE = {
    init: (options) => nostrLite.init(options),
    launch: (startScreen) => nostrLite.launch(startScreen),
    logout: () => nostrLite.logout(),
    
    // Embedded modal method
    embed: (container, options) => nostrLite.embed(container, options),
    
    // CSS-only theme management API
    switchTheme: (themeName) => nostrLite.switchTheme(themeName),
    getCurrentTheme: () => nostrLite.getCurrentTheme(),
    getAvailableThemes: () => nostrLite.getAvailableThemes(),
    
    // Floating tab management API
    showFloatingTab: () => nostrLite.showFloatingTab(),
    hideFloatingTab: () => nostrLite.hideFloatingTab(),
    toggleFloatingTab: () => nostrLite.toggleFloatingTab(),
    updateFloatingTab: (options) => nostrLite.updateFloatingTab(options),
    getFloatingTabState: () => nostrLite.getFloatingTabState(),
    
    // GLOBAL AUTHENTICATION STATE API - Single Source of Truth
    getAuthState: getAuthState,
    setAuthState: setAuthState,
    clearAuthState: clearAuthState,
    
    // Expose for debugging
    _extensionBridge: nostrLite.extensionBridge,
    _instance: nostrLite
  };
  
  console.log('NOSTR_LOGIN_LITE: Library loaded and ready');
  console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize');
  console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions');
} else {
  // Node.js environment
  module.exports = { NostrLite };
}
