import { describe, expect, it } from 'vitest';
import { BLOCKCHAIN_NETWORK, HDWallet } from '../src/index';

const MNEMONIC = 'test test test test test test test test test test test junk';

describe('HDWallet', () => {
	describe('Ethereum', () => {
		it('deriva siempre la misma direccion (determinismo)', () => {
			const wallet1 = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC);

			const result1 = wallet1.generate("44'/60'/0'/0", 0);

			expect(result1.address).toBe('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266');
		});

		it('genera direccion valida (formato 0x)', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC);

			const { address } = wallet.generate("44'/60'/0'/0", 0);

			expect(address.startsWith('0x')).toBe(true);
			expect(address.length).toBe(42);
		});

		it('incluye privateKey cuando includePrivateKey=true', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC, true, true);

			const result = wallet.generate("44'/60'/0'/0", 0);

			expect(result.privateKey).toBeDefined();
			expect(result.privateKey?.length).toBeGreaterThan(0);
		});

		it('genera publicKey válida', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC);

			const { publicKey } = wallet.generate("44'/60'/0'/0", 0);

			expect(publicKey).toMatch(/^0x[0-9a-fA-F]+$/);
		});
	});

	describe('Bitcoin (SegWit)', () => {
		it('genera direccion bech32 valida', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.BITCOIN, MNEMONIC);

			const { address } = wallet.generate("84'/0'/0'/0", 0);

			expect(address.startsWith('bc1')).toBe(true);
		});

		it('determinismo bitcoin', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.BITCOIN, MNEMONIC);

			const a = wallet.generate("84'/0'/0'/0", 0);
			const b = wallet.generate("84'/0'/0'/0", 0);

			expect(a.address).toBe(b.address);
		});
	});

	describe('Litecoin', () => {
		it('genera direccion valida', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.LITECOIN, MNEMONIC);

			const { address } = wallet.generate("84'/2'/0'/0", 0);

			expect(address).toBeDefined();
			expect(address.length).toBeGreaterThan(0);
		});
	});

	describe('Tron', () => {
		it('genera direccion valida (Base58 tron)', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.TRON, MNEMONIC);

			const { address } = wallet.generate("44'/195'/0'/0", 0);

			expect(address.startsWith('T')).toBe(true);
		});

		it('deriva siempre la misma direccion (determinismo)', () => {
			const wallet1 = new HDWallet(BLOCKCHAIN_NETWORK.TRON, MNEMONIC);

			const result1 = wallet1.generate("44'/195'/0'/0", 0);

			expect(result1.address).toBe('TWer2Ygk5TEheHp3TPuYeqxmB6SsGZmaL6');
		});
	});

	describe('Ripple', () => {
		it('genera direccion ripple valida', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.RIPPLE, MNEMONIC);

			const { address } = wallet.generate("44'/144'/0'/0", 0);

			expect(address.startsWith('r')).toBe(true);
		});
	});

	describe('Edge cases', () => {
		it('indices distintos generan direcciones distintas', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC);

			const a = wallet.generate("44'/60'/0'/0", 0);
			const b = wallet.generate("44'/60'/0'/0", 1);

			expect(a.address).not.toBe(b.address);
		});

		it('paths distintos generan direcciones distintas', () => {
			const wallet = new HDWallet(BLOCKCHAIN_NETWORK.ETHEREUM, MNEMONIC);

			const a = wallet.generate("44'/60'/0'/0", 0);
			const b = wallet.generate("44'/60'/1'/0", 0);

			expect(a.address).not.toBe(b.address);
		});
	});
});
