export class XCUQuantumCipher {
	private key: CryptoKey | null = null;
	private roomSecret: string;

	constructor(roomSecret: string) {
		this.roomSecret = roomSecret;
	}

	public async initialize() {
		const enc = new TextEncoder();
		const keyMaterial = await crypto.subtle.importKey(
			"raw",
			enc.encode(this.roomSecret.padEnd(32, "0").slice(0, 32)), // 256-bit derivation
			{ name: "PBKDF2" },
			false,
			["deriveBits", "deriveKey"]
		);

		this.key = await crypto.subtle.deriveKey(
			{
				name: "PBKDF2",
				salt: enc.encode("xcom_ultra_salt_v1"),
				iterations: 100000,
				hash: "SHA-256",
			},
			keyMaterial,
			{ name: "AES-GCM", length: 256 },
			false,
			["encrypt", "decrypt"]
		);
	}

	public async encrypt(plaintext: string): Promise<Uint8Array> {
		if (!this.key) throw new Error("Cipher not initialized");
		const iv = crypto.getRandomValues(new Uint8Array(12));
		const enc = new TextEncoder();
		const ciphertext = await crypto.subtle.encrypt(
			{
				name: "AES-GCM",
				iv: iv,
			},
			this.key,
			enc.encode(plaintext)
		);
		const result = new Uint8Array(iv.length + ciphertext.byteLength);
		result.set(iv, 0);
		result.set(new Uint8Array(ciphertext), iv.length);
		return result;
	}

	public async decrypt(data: Uint8Array): Promise<string> {
		if (!this.key) throw new Error("Cipher not initialized");
		const iv = data.slice(0, 12);
		const ciphertext = data.slice(12);
		const plaintext = await crypto.subtle.decrypt(
			{
				name: "AES-GCM",
				iv: iv,
			},
			this.key,
			ciphertext
		);
		const dec = new TextDecoder();
		return dec.decode(plaintext);
	}
}
