import { ShadeSessionManager } from '../../packages/shade-core/src/index.js';
import { SubtleCryptoProvider, MemoryStorage } from '../../packages/shade-crypto-web/src/index.js';

const crypto = new SubtleCryptoProvider();

async function main() {
  console.log('=== Shade Basic Conversation ===\n');

  // Set up Alice and Bob with separate storage
  const alice = new ShadeSessionManager(crypto, new MemoryStorage());
  const bob = new ShadeSessionManager(crypto, new MemoryStorage());

  await alice.initialize();
  await bob.initialize();

  // Show fingerprints (safety numbers for verification)
  console.log('Alice fingerprint:', await alice.getIdentityFingerprint());
  console.log('Bob fingerprint:  ', await bob.getIdentityFingerprint());
  console.log();

  // Bob generates one-time prekeys (would be uploaded to a prekey server)
  const bobOTPKs = await bob.generateOneTimePreKeys(5);
  const bobBundle = await bob.createPreKeyBundle();
  bobBundle.oneTimePreKey = {
    keyId: bobOTPKs[0].keyId,
    publicKey: bobOTPKs[0].keyPair.publicKey,
  };

  // Alice fetches Bob's bundle (here: directly) and starts a session
  await alice.initSessionFromBundle('bob', bobBundle);

  // Alice → Bob
  console.log('→ Alice encrypts: "Hello Bob!"');
  const msg1 = await alice.encrypt('bob', 'Hello Bob!');
  const plain1 = await bob.decrypt('alice', msg1);
  console.log(`← Bob decrypts:   "${plain1}"`);

  // Bob → Alice (triggers DH ratchet step)
  console.log('\n→ Bob encrypts: "Hi Alice, got your message"');
  const msg2 = await bob.encrypt('alice', 'Hi Alice, got your message');
  const plain2 = await alice.decrypt('bob', msg2);
  console.log(`← Alice decrypts: "${plain2}"`);

  // Several more turns
  console.log('\n=== Continued conversation (each message has a unique key) ===');
  const conversation = [
    ['alice', 'How are you?'],
    ['bob', 'Doing well!'],
    ['alice', 'Want to grab coffee?'],
    ['bob', 'Sure, when?'],
  ] as const;

  for (const [from, text] of conversation) {
    const sender = from === 'alice' ? alice : bob;
    const receiver = from === 'alice' ? bob : alice;
    const recvAddr = from === 'alice' ? 'alice' : 'bob';
    const sendAddr = from === 'alice' ? 'bob' : 'alice';

    const env = await sender.encrypt(sendAddr, text);
    const plain = await receiver.decrypt(recvAddr, env);
    console.log(`${from === 'alice' ? 'Alice' : 'Bob  '}: "${plain}"`);
  }

  console.log('\n=== Done. Every message used a unique key. ===');
}

main().catch(console.error);
