import { Mnemonic } from './index';
import { DomainError } from '@/shared/exceptions/domain.exception';

describe('Mnemonic ValueObject', () => {
  describe('generate', () => {
    it('应该生成有效的12个单词助记词', () => {
      const mnemonic = Mnemonic.generate();

      expect(mnemonic).toBeDefined();
      expect(mnemonic.value).toBeDefined();

      const words = mnemonic.getWords();
      expect(words).toHaveLength(12);
      expect(words.every((word) => word.length > 0)).toBe(true);
    });

    it('生成的助记词应该能转换为 seed', () => {
      const mnemonic = Mnemonic.generate();
      const seed = mnemonic.toSeed();

      expect(seed).toBeDefined();
      expect(seed).toBeInstanceOf(Uint8Array);
      expect(seed.length).toBeGreaterThan(0);
    });

    it('每次生成的助记词应该不同', () => {
      const mnemonic1 = Mnemonic.generate();
      const mnemonic2 = Mnemonic.generate();

      expect(mnemonic1.value).not.toBe(mnemonic2.value);
    });
  });

  describe('create', () => {
    it('应该接受有效的助记词字符串', () => {
      const validMnemonic =
        'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
      const mnemonic = Mnemonic.create(validMnemonic);

      expect(mnemonic.value).toBe(validMnemonic);
    });

    it('应该拒绝无效的助记词', () => {
      const invalidMnemonic = 'invalid invalid invalid';

      expect(() => {
        Mnemonic.create(invalidMnemonic);
      }).toThrow(DomainError);
    });

    it('应该拒绝空字符串', () => {
      expect(() => {
        Mnemonic.create('');
      }).toThrow(DomainError);
    });

    it('应该拒绝非英文单词', () => {
      const invalidMnemonic =
        '中文 助记词 测试 中文 助记词 测试 中文 助记词 测试 中文 助记词';

      expect(() => {
        Mnemonic.create(invalidMnemonic);
      }).toThrow(DomainError);
    });
  });

  describe('getWords', () => {
    it('应该返回单词数组', () => {
      const mnemonic = Mnemonic.generate();
      const words = mnemonic.getWords();

      expect(Array.isArray(words)).toBe(true);
      expect(words.length).toBe(12);
    });
  });

  describe('toSeed', () => {
    it('相同的助记词应该生成相同的 seed', () => {
      const mnemonicStr =
        'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
      const mnemonic1 = Mnemonic.create(mnemonicStr);
      const mnemonic2 = Mnemonic.create(mnemonicStr);

      const seed1 = mnemonic1.toSeed();
      const seed2 = mnemonic2.toSeed();

      expect(seed1).toEqual(seed2);
    });

    it('不同的助记词应该生成不同的 seed', () => {
      const mnemonic1 = Mnemonic.generate();
      const mnemonic2 = Mnemonic.generate();

      const seed1 = mnemonic1.toSeed();
      const seed2 = mnemonic2.toSeed();

      expect(seed1).not.toEqual(seed2);
    });
  });

  describe('equals', () => {
    it('相同的助记词应该相等', () => {
      const mnemonicStr =
        'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
      const mnemonic1 = Mnemonic.create(mnemonicStr);
      const mnemonic2 = Mnemonic.create(mnemonicStr);

      expect(mnemonic1.equals(mnemonic2)).toBe(true);
    });

    it('不同的助记词应该不相等', () => {
      const mnemonic1 = Mnemonic.generate();
      const mnemonic2 = Mnemonic.generate();

      expect(mnemonic1.equals(mnemonic2)).toBe(false);
    });
  });
});
