import { describe, it, expect, beforeEach } from 'bun:test';
import { detectEncryptionMode } from './../lib/seedpgp';
import {
    encryptJsonToBlob,
    decryptBlobToJson,
    destroySessionKey,
    getSessionKey,
} from './../lib/sessionCrypto';

describe('Security Fixes Verification', () => {
    describe('F-02: Regex Fix for SeedQR detection', () => {
        it('should correctly detect a standard numeric SeedQR', () => {
            // A 48-digit string, representing 12 words
            const numericSeedQR = '000011112222333344445555666677778888999901234567';
            const mode = detectEncryptionMode(numericSeedQR);
            expect(mode).toBe('seedqr');
        });

        it('should not detect a short numeric string as SeedQR', () => {
            const shortNumeric = '1234567890'; // 10 digits - too short for SeedQR
            const mode = detectEncryptionMode(shortNumeric);
            // ✅ FIXED: Short numeric strings should NOT be detected as SeedQR
            // (They may be detected as 'krux' if they match Base43 charset, which is fine)
            expect(mode).not.toBe('seedqr');
        });

        it('should not detect a mixed-character string as numeric SeedQR', () => {
            const mixedString = '00001111222233334444555566667777888899990123456a';
            const mode = detectEncryptionMode(mixedString);
            expect(mode).not.toBe('seedqr');
        });
    });

    describe('F-01: Session Key Rotation Data Loss Fix', () => {
        beforeEach(() => {
            destroySessionKey();
        });

        it('should include a keyId in the encrypted blob', async () => {
            const data = { secret: 'hello world' };
            const blob = await encryptJsonToBlob(data);
            expect(blob.keyId).toBeDefined();
            expect(typeof blob.keyId).toBe('string');
            expect(blob.keyId.length).toBeGreaterThan(0); // Additional check
        });

        it('should successfully decrypt a blob with the correct keyId', async () => {
            const data = { secret: 'this is a test' };
            const blob = await encryptJsonToBlob(data);
            const decrypted = await decryptBlobToJson(blob);
            expect(decrypted).toEqual(data);
        });

        it('should throw an error if the key is rotated before decryption', async () => {
            const data = { secret: 'will be lost' };
            const blob = await encryptJsonToBlob(data);

            // Force key rotation by destroying the current one and getting a new one
            destroySessionKey();
            await getSessionKey(); // Generates a new key with a new keyId

            // Decryption should now fail because the keyId in the blob does not match
            await expect(decryptBlobToJson(blob)).rejects.toThrow(
                'Session expired. The encryption key has rotated. Please re-enter your seed phrase.'
            );
        });
    });
});