import { getCryptoBackend } from './backend.js';
import { decryptFrom, encryptFor, type EncryptedEnvelope } from './box.js';

// Sender-Key (Signal-style) helpers — one symmetric XSalsa20-Poly1305 key per
// conversation, wrapped with `crypto_box` for each recipient device's pubkey.
//
// Flow:
//   - generateConvKey() produces 32 random bytes
//   - wrapConvKeyForRecipient() encrypts the conv-key with sender's private key
//     and recipient's pubkey -> stored in `conversation_keys` table
//   - unwrapConvKey() reverses it on the receiving side
//   - encryptWithConvKey()/decryptWithConvKey() do the message-payload work

export function generateConvKey(): Uint8Array {
  const backend = getCryptoBackend();
  return backend.randomBytes(backend.secretboxKeyLength);
}

export async function wrapConvKeyForRecipient(
  convKey: Uint8Array,
  recipientPublicKey: Uint8Array,
  senderPrivateKey: Uint8Array,
): Promise<EncryptedEnvelope> {
  return encryptFor(convKey, recipientPublicKey, senderPrivateKey);
}

export async function unwrapConvKey(
  encryptedKey: Uint8Array,
  nonce: Uint8Array,
  senderPublicKey: Uint8Array,
  recipientPrivateKey: Uint8Array,
): Promise<Uint8Array> {
  return decryptFrom(encryptedKey, nonce, senderPublicKey, recipientPrivateKey);
}

export interface ConvCipher {
  ciphertext: Uint8Array;
  nonce: Uint8Array;
}

export function encryptWithConvKey(
  plaintext: Uint8Array,
  convKey: Uint8Array,
): ConvCipher {
  const backend = getCryptoBackend();
  const nonce = backend.randomBytes(backend.secretboxNonceLength);
  const ciphertext = backend.secretbox(plaintext, nonce, convKey);
  return { ciphertext, nonce };
}

export function decryptWithConvKey(
  ciphertext: Uint8Array,
  nonce: Uint8Array,
  convKey: Uint8Array,
): Uint8Array {
  const backend = getCryptoBackend();
  return backend.secretboxOpen(ciphertext, nonce, convKey);
}
