/**
 * NDK Authentication Patterns
 * 
 * Examples from: src/lib/stores/auth.ts
 */

import NDK from '@nostr-dev-kit/ndk'
import { NDKNip07Signer, NDKPrivateKeySigner, NDKNip46Signer } from '@nostr-dev-kit/ndk'

// ============================================================
// NIP-07 - BROWSER EXTENSION SIGNER
// ============================================================

const loginWithExtension = async (ndk: NDK) => {
  try {
    // Create NIP-07 signer (browser extension like Alby, nos2x)
    const signer = new NDKNip07Signer()
    
    // Wait for signer to be ready
    await signer.blockUntilReady()
    
    // Set signer on NDK instance
    ndk.signer = signer
    
    // Get authenticated user
    const user = await signer.user()
    
    console.log('✅ Logged in via extension:', user.npub)
    return { user, signer }
  } catch (error) {
    console.error('❌ Extension login failed:', error)
    throw new Error('Failed to login with browser extension. Is it installed?')
  }
}

// ============================================================
// PRIVATE KEY SIGNER
// ============================================================

const loginWithPrivateKey = async (ndk: NDK, privateKeyHex: string) => {
  try {
    // Validate private key format (64 hex characters)
    if (!/^[0-9a-f]{64}$/.test(privateKeyHex)) {
      throw new Error('Invalid private key format')
    }
    
    // Create private key signer
    const signer = new NDKPrivateKeySigner(privateKeyHex)
    
    // Wait for signer to be ready
    await signer.blockUntilReady()
    
    // Set signer on NDK instance
    ndk.signer = signer
    
    // Get authenticated user
    const user = await signer.user()
    
    console.log('✅ Logged in with private key:', user.npub)
    return { user, signer }
  } catch (error) {
    console.error('❌ Private key login failed:', error)
    throw error
  }
}

// ============================================================
// NIP-46 - REMOTE SIGNER (BUNKER)
// ============================================================

const loginWithNip46 = async (
  ndk: NDK,
  bunkerUrl: string,
  localPrivateKey?: string
) => {
  try {
    // Create or use existing local signer
    const localSigner = localPrivateKey
      ? new NDKPrivateKeySigner(localPrivateKey)
      : NDKPrivateKeySigner.generate()
    
    // Create NIP-46 remote signer
    const remoteSigner = new NDKNip46Signer(ndk, bunkerUrl, localSigner)
    
    // Wait for signer to be ready (may require user approval)
    await remoteSigner.blockUntilReady()
    
    // Set signer on NDK instance
    ndk.signer = remoteSigner
    
    // Get authenticated user
    const user = await remoteSigner.user()
    
    console.log('✅ Logged in via NIP-46:', user.npub)
    
    // Store local signer key for reconnection
    return {
      user,
      signer: remoteSigner,
      localSignerKey: localSigner.privateKey
    }
  } catch (error) {
    console.error('❌ NIP-46 login failed:', error)
    throw error
  }
}

// ============================================================
// AUTO-LOGIN FROM LOCAL STORAGE
// ============================================================

const STORAGE_KEYS = {
  AUTO_LOGIN: 'nostr:auto-login',
  LOCAL_SIGNER: 'nostr:local-signer',
  BUNKER_URL: 'nostr:bunker-url',
  ENCRYPTED_KEY: 'nostr:encrypted-key'
}

const getAuthFromStorage = async (ndk: NDK) => {
  try {
    // Check if auto-login is enabled
    const autoLogin = localStorage.getItem(STORAGE_KEYS.AUTO_LOGIN)
    if (autoLogin !== 'true') {
      return null
    }
    
    // Try NIP-46 bunker connection
    const privateKey = localStorage.getItem(STORAGE_KEYS.LOCAL_SIGNER)
    const bunkerUrl = localStorage.getItem(STORAGE_KEYS.BUNKER_URL)
    
    if (privateKey && bunkerUrl) {
      return await loginWithNip46(ndk, bunkerUrl, privateKey)
    }
    
    // Try encrypted private key
    const encryptedKey = localStorage.getItem(STORAGE_KEYS.ENCRYPTED_KEY)
    if (encryptedKey) {
      // Would need decryption password from user
      return { needsPassword: true, encryptedKey }
    }
    
    // Fallback to extension
    return await loginWithExtension(ndk)
  } catch (error) {
    console.error('Auto-login failed:', error)
    return null
  }
}

// ============================================================
// SAVE AUTH TO STORAGE
// ============================================================

const saveAuthToStorage = (
  method: 'extension' | 'private-key' | 'nip46',
  data?: {
    privateKey?: string
    bunkerUrl?: string
    encryptedKey?: string
  }
) => {
  // Enable auto-login
  localStorage.setItem(STORAGE_KEYS.AUTO_LOGIN, 'true')
  
  if (method === 'nip46' && data?.privateKey && data?.bunkerUrl) {
    localStorage.setItem(STORAGE_KEYS.LOCAL_SIGNER, data.privateKey)
    localStorage.setItem(STORAGE_KEYS.BUNKER_URL, data.bunkerUrl)
  } else if (method === 'private-key' && data?.encryptedKey) {
    localStorage.setItem(STORAGE_KEYS.ENCRYPTED_KEY, data.encryptedKey)
  }
  // Extension doesn't need storage
}

// ============================================================
// LOGOUT
// ============================================================

const logout = (ndk: NDK) => {
  // Remove signer from NDK
  ndk.signer = undefined
  
  // Clear all auth storage
  Object.values(STORAGE_KEYS).forEach(key => {
    localStorage.removeItem(key)
  })
  
  console.log('✅ Logged out successfully')
}

// ============================================================
// GET CURRENT USER
// ============================================================

const getCurrentUser = async (ndk: NDK) => {
  if (!ndk.signer) {
    return null
  }
  
  try {
    const user = await ndk.signer.user()
    return {
      pubkey: user.pubkey,
      npub: user.npub,
      profile: await user.fetchProfile()
    }
  } catch (error) {
    console.error('Failed to get current user:', error)
    return null
  }
}

// ============================================================
// USAGE EXAMPLE
// ============================================================

async function authExample(ndk: NDK) {
  // Try auto-login first
  let auth = await getAuthFromStorage(ndk)
  
  if (!auth) {
    // Manual login options
    console.log('Choose login method:')
    console.log('1. Browser Extension (NIP-07)')
    console.log('2. Private Key')
    console.log('3. Remote Signer (NIP-46)')
    
    // Example: login with extension
    auth = await loginWithExtension(ndk)
    saveAuthToStorage('extension')
  }
  
  if (auth && 'needsPassword' in auth) {
    // Handle encrypted key case
    console.log('Password required for encrypted key')
    return
  }
  
  // Get current user info
  const currentUser = await getCurrentUser(ndk)
  console.log('Current user:', currentUser)
  
  // Logout when done
  // logout(ndk)
}

export {
  loginWithExtension,
  loginWithPrivateKey,
  loginWithNip46,
  getAuthFromStorage,
  saveAuthToStorage,
  logout,
  getCurrentUser
}

