// Debug script to extract all intermediate values from nostr-tools NIP-44
const { v2 } = require('./nostr-tools/nip44.js');
const { bytesToHex, hexToBytes } = require('@noble/hashes/utils');

// Test vector 1: single char 'a'
console.log('=== NOSTR-TOOLS DEBUG: Single char "a" ===');
const sec1 = hexToBytes('0000000000000000000000000000000000000000000000000000000000000001');
const sec2 = hexToBytes('0000000000000000000000000000000000000000000000000000000000000002');
const nonce = hexToBytes('0000000000000000000000000000000000000000000000000000000000000001');
const plaintext = 'a';

// Step 1: Get public keys
const { schnorr } = require('@noble/curves/secp256k1');
const pub1 = bytesToHex(schnorr.getPublicKey(sec1));
const pub2 = bytesToHex(schnorr.getPublicKey(sec2));
console.log('pub1:', pub1);
console.log('pub2:', pub2);

// Step 2: Get conversation key
const conversationKey = v2.utils.getConversationKey(sec1, pub2);
console.log('conversation_key:', bytesToHex(conversationKey));

// Step 3: Get shared secret (raw ECDH)
const { secp256k1 } = require('@noble/curves/secp256k1');
const sharedPoint = secp256k1.getSharedSecret(sec1, '02' + pub2);
const sharedSecret = sharedPoint.subarray(1, 33); // X coordinate only
console.log('ecdh_shared_secret:', bytesToHex(sharedSecret));

// Step 4: Get message keys using internal function
const hkdf = require('@noble/hashes/hkdf');
const { sha256 } = require('@noble/hashes/sha256');

// HKDF Extract step
const salt = new TextEncoder().encode('nip44-v2');
const prk = hkdf.extract(sha256, sharedSecret, salt);
console.log('hkdf_extract_result:', bytesToHex(prk));

// HKDF Expand step  
const messageKeys = hkdf.expand(sha256, prk, nonce, 76);
const chachaKey = messageKeys.subarray(0, 32);
const chachaNonce = messageKeys.subarray(32, 44);
const hmacKey = messageKeys.subarray(44, 76);

console.log('chacha_key:', bytesToHex(chachaKey));
console.log('chacha_nonce:', bytesToHex(chachaNonce));
console.log('hmac_key:', bytesToHex(hmacKey));

// Step 5: Pad the plaintext
function pad(plaintext) {
    const utf8Encoder = new TextEncoder();
    const unpadded = utf8Encoder.encode(plaintext);
    const unpaddedLen = unpadded.length;
    
    // Length prefix (big-endian u16)
    const prefix = new Uint8Array(2);
    new DataView(prefix.buffer).setUint16(0, unpaddedLen, false);
    
    // Calculate padded length
    function calcPaddedLen(len) {
        if (len <= 32) return 32;
        const nextPower = 1 << (Math.floor(Math.log2(len - 1)) + 1);
        const chunk = nextPower <= 256 ? 32 : nextPower / 8;
        return chunk * (Math.floor((len - 1) / chunk) + 1);
    }
    
    const paddedLen = calcPaddedLen(unpaddedLen + 2);
    const suffix = new Uint8Array(paddedLen - 2 - unpaddedLen);
    
    // Combine: prefix + plaintext + padding
    const result = new Uint8Array(paddedLen);
    result.set(prefix);
    result.set(unpadded, 2);
    result.set(suffix, 2 + unpaddedLen);
    
    return result;
}

const paddedPlaintext = pad(plaintext);
console.log('padded_plaintext:', bytesToHex(paddedPlaintext));
console.log('padded_length:', paddedPlaintext.length);

// Step 6: ChaCha20 encrypt
const { chacha20 } = require('@noble/ciphers/chacha');
const ciphertext = chacha20(chachaKey, chachaNonce, paddedPlaintext);
console.log('ciphertext:', bytesToHex(ciphertext));

// Step 7: HMAC with AAD
const { hmac } = require('@noble/hashes/hmac');
const { concatBytes } = require('@noble/hashes/utils');
const aad = concatBytes(nonce, ciphertext);
console.log('aad_data:', bytesToHex(aad));
const mac = hmac(sha256, hmacKey, aad);
console.log('mac:', bytesToHex(mac));

// Step 8: Final payload
const { base64 } = require('@scure/base');
const payload = concatBytes(new Uint8Array([2]), nonce, ciphertext, mac);
console.log('raw_payload:', bytesToHex(payload));
const base64Payload = base64.encode(payload);
console.log('final_payload:', base64Payload);

// Expected from test vectors
console.log('expected_payload:', 'AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABee0G5VSK0/9YypIObAtDKfYEAjD35uVkHyB0F4DwrcNaCXlCWZKaArsGrY6M9wnuTMxWfp1RTN9Xga8no+kF5Vsb');

// Now let's also test the full encrypt function
const fullEncrypt = v2.encrypt(plaintext, conversationKey, nonce);
console.log('v2.encrypt_result:', fullEncrypt);
