import { Wallet } from './Wallet';
import { ethers } from 'ethers';

export class ETHWallet extends Wallet {
  constructor(wallet: ethers.Wallet) {
    super(wallet);
  }

  get address(): string {
    return this.signer.address;
  }

  getPrivateKey(): string {
    const privateKey = this.signer.privateKey;
    return privateKey;
  }

  getSeedsPhrase(): { phrase: string; path: string; locale: string } {
    return this.signer.mnemonic;
  }

  static validate(privateKey: string): boolean {
    try {
      const etherWallet = new ethers.Wallet(privateKey);
      if (etherWallet instanceof ethers.Wallet) {
        return true;
      }
      return false;
    } catch (error) {
      return false;
    }
  }
  static generateWallet(): Wallet {
    const etherWallet = ethers.Wallet.createRandom();
    return new ETHWallet(etherWallet);
  }

  /**@internal*/
  private static hdNodeFromSeed(seed: Uint8Array, derivePath: string): Wallet {
    const hdNode = ethers.utils.HDNode.fromSeed(seed).derivePath(derivePath);
    const etherWallet = new ethers.Wallet(hdNode);

    return new ETHWallet(etherWallet);
  }

  static fromSeed(seed: Uint8Array): Wallet {
    const derivePath = "m/44'/60'/0'/0/0";
    return this.hdNodeFromSeed(seed, derivePath);
  }

  static fromPrivateKey(secretKey: string): Wallet {
    const etherWallet = new ethers.Wallet(secretKey);
    return new ETHWallet(etherWallet);
  }

  static async fromMnemonic(mnemonic: string): Promise<Wallet> {
    const seed = await this.mnemonicToSeed(mnemonic);
    return this.fromSeed(seed);
  }

  static async generateWalletWithIndex(
    seed: Buffer,
    index: number
  ): Promise<Wallet> {
    const derivePath = `m/44'/60'/0'/0/${index}`;
    return this.hdNodeFromSeed(seed, derivePath);
  }
}
