import 'dart:typed_data';

import 'package:flutter_bitcoin/flutter_bitcoin.dart' as btcWallet;
import 'package:flutter_wallet/tools/YSNetWork.dart';
import 'package:flutter_wallet/tools/YSSqflite.dart';
import 'package:hex/hex.dart';
import 'YSAes.dart';
import 'YSTools.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:bip32/bip32.dart' as bip32;
import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart';
import 'package:wallet/wallet.dart' as ysWallet;


class YSBipManager {

  static setKeystore(String keystore,String password,{bool isInto = false}) async{
    try{
      Wallet wallet = Wallet.fromJson(keystore, password);
      String privateKey = bytesToHex(wallet.privateKey.privateKey);
      YSData data = YSData();
      String word = getMnemonic();
      YSSharedPreferences.setStringValue('word', 'word');
      YSSqflite sqflite = YSSqflite().init();
      int id = 0;
      if(YSData().typeId=='TRON-HD'){
        Map tronMap = getTronCode2(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, tronMap['word'], tronMap['privateKey'], tronMap['pubicKey'],0));
      }else if(YSData().typeId=='BTC-HD'){
        Map btcMap = await getBtcCode2(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, btcMap['word'], btcMap['privateKey'], btcMap['pubicKey'],0));
      }else{
        EthereumAddress pubicKey = await getPublicAddress(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, word, privateKey, pubicKey.hexEip55,0));
      }
      return id!=0;
    }catch(e){
      ysFlutterToast('$e');
      return false;
    }
  }

  static setObserve(String address,{bool isInto = false}) async{
    try{
      String privateKey = '';
      YSData data = YSData();
      String word = getMnemonic();
      YSSharedPreferences.setStringValue('word', 'word');
      YSSqflite sqflite = YSSqflite().init();
      int id = 0;
      id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, word, privateKey, address,0));
      return id!=0;
    }catch(e){
      ysFlutterToast('$e');
      return false;
    }
  }

  static setPrivate(String privateKey,{bool isInto = false}) async{
    YSData data = YSData();
    try{
      String word = getMnemonic();
      YSSharedPreferences.setStringValue('word', 'word');
      YSSqflite sqflite = YSSqflite().init();
      int id = 0;
      if(YSData().typeId=='TRON-HD'){
        Map tronMap = getTronCode2(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, tronMap['word'], tronMap['privateKey'], tronMap['pubicKey'],0));
      }else if(YSData().typeId=='BTC-HD'){
        Map btcMap = await getBtcCode2(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, btcMap['word'], btcMap['privateKey'], btcMap['pubicKey'],0));
      }else{
        EthereumAddress pubicKey = await getPublicAddress(privateKey);
        id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, word, privateKey, pubicKey.hexEip55,0));
      }
      return id!=0;
    }catch(e){
      LogUtil.d(e);
      return false;
    }
  }

  static Future<bool> setMnemonic(String word,{bool isInto = false}) async{
    YSData data = YSData();
    try{
      YSSharedPreferences.setStringValue('word', word);
      bool isFirst = await YSSharedPreferences.getBoolValue('isFirst')??true;
      int id = 0;
      if(isFirst&&isInto==false){
        // id = 1;
        for (var element in YSData().typeArray) {
          String name = '${element['name']}'.replaceAll('-', '').replaceAll(' ', '');
          LogUtil.d(name);
          YSSqflite sqflite = YSSqflite().init(name: name);
          if(element['id']=='TRON-HD'){
            Map tronMap = getTronCode(word);
            if(tronMap.isNotEmpty)sqflite.rawInsert(YSWalletDbData(data.name, data.password, tronMap['word'], tronMap['privateKey'], tronMap['pubicKey'],0),name: name);
          }else if(element['id']=='BTC-HD'){
            Map btcMap = await getBtcCode(word);
            if(btcMap.isNotEmpty)sqflite.rawInsert(YSWalletDbData(data.name, data.password, btcMap['word'], btcMap['privateKey'], btcMap['pubicKey'],0),name: name);
          }else{
            String privateKey = getPrivateKey(word);
            EthereumAddress pubicKey = await getPublicAddress(privateKey);
            id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, word, privateKey, pubicKey.hexEip55,0),name: name);
          }
        }
        YSSharedPreferences.setBoolValue('isFirst', false);
      }else{
        LogUtil.d('obj2');
        YSSqflite sqflite = YSSqflite().init();
        if(YSData().typeId=='TRON-HD'){
          Map tronMap = getTronCode(word);
          id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, tronMap['word'], tronMap['privateKey'], tronMap['pubicKey'],0));
        }else if(YSData().typeId=='BTC-HD'){
          Map btcMap = await getBtcCode(word);
          sqflite.rawInsert(YSWalletDbData(data.name, data.password, btcMap['word'], btcMap['privateKey'], btcMap['pubicKey'],0));
        }else{
          String privateKey = getPrivateKey(word);
          EthereumAddress pubicKey = await getPublicAddress(privateKey);
          id = await sqflite.rawInsert(YSWalletDbData(data.name, data.password, word, privateKey, pubicKey.hexEip55,0));
        }
      }
      return id!=0;
    }catch(e){
      LogUtil.d(e);
      return false;
    }
  }

  static String getMnemonic() {
    String randomMnemonic = bip39.generateMnemonic();
    LogUtil.d(randomMnemonic);
    return randomMnemonic;
  }

  static bool checkMnemonic(String mnemonic) {
    return bip39.validateMnemonic(mnemonic);
  }

  static String getPrivateKey(String mnemonic) {
    final seed = bip39.mnemonicToSeed(mnemonic);
    final root = bip32.BIP32.fromSeed(seed);
    final child1 = root.derivePath("m/44'/60'/0'/0/0");
    String hex = bytesToHex(child1.privateKey!.toList());
    LogUtil.d(hex);
    return hex;
  }

  static Future<EthereumAddress> getPublicAddress(String privateKey) async {
    final private = EthPrivateKey.fromHex(privateKey);
    final address = private.address;
    LogUtil.d(address);
    return address;
  }

 static Map getTronCode(String mnemonic) {
    const passphrase = '';
    final seed = ysWallet.mnemonicToSeed(mnemonic.split(' '), passphrase: passphrase);
    final master = ysWallet.ExtendedPrivateKey.master(seed, ysWallet.xprv);
    final root = master.forPath("m/44'/195'/0'/0/0");

    final privateKey = ysWallet.PrivateKey((root as ysWallet.ExtendedPrivateKey).key);
    final publicKey = ysWallet.tron.createPublicKey(privateKey);
    final address = ysWallet.tron.createAddress(publicKey);
    return {'word':mnemonic,'privateKey':privateKey.value.toRadixString(16),'pubicKey':address};
  }
  static Map getTronCode2(String private16) {
    String word = getMnemonic();
    word = '$word ysssss';
    final privateKey =  ysWallet.PrivateKey(BigInt.parse(private16, radix: 16));
    final publicKey = ysWallet.tron.createPublicKey(privateKey);
    final address = ysWallet.tron.createAddress(publicKey);
    return {'word':word,'privateKey':private16,'pubicKey':address};
  }
  // static Future<Map> getBtcCode(String mnemonic) async{
  //   String seed = bip39.mnemonicToSeedHex(mnemonic);
  //   bip32.BIP32 root = bip32.BIP32.fromSeed(Uint8List.fromList(HEX.decode(seed)));
  //
  //   btcWallet.ECPair keyPair = btcWallet.ECPair.fromPrivateKey(root.privateKey!);
  //   String private = keyPair.toWIF();
  //   String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
  //   Map dict = await YSNetWork.httpNetwork(api: 'bitconinp2sh', request: {'prikey':privateS});
  //   if(dict.isNotEmpty){
  //     String address = dict['data']??'';
  //     return {'word':mnemonic,'privateKey':private,'pubicKey':address};
  //   }else{
  //     return {};
  //   }
  // }

  static Future<Map> getBtcCode(String mnemonic) async{
    const passphrase = '';
    final seed = ysWallet.mnemonicToSeed(mnemonic.split(' '), passphrase: passphrase);
    final master = ysWallet.ExtendedPrivateKey.master(seed, ysWallet.xprv);
    final root = master.forPath("m/49'/0'/0'/0/0");

    btcWallet.ECPair keyPair = btcWallet.ECPair.fromPrivateKey(HEX.decode((root as ysWallet.ExtendedPrivateKey).key.toRadixString(16)) as Uint8List);
    String private = keyPair.toWIF();
    String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
    Map dict = await YSNetWork.httpNetwork(api: 'bitconinp2sh', request: {'prikey':privateS});
    if(dict.isNotEmpty){
      String address = dict['data']??'';
      // LogUtil.d('getBtcCode=======$dict');
      // return {};
      return {'word':mnemonic,'privateKey':private,'pubicKey':address};
    }else{
      return {};
    }
  }
  static Future<Map> getBtcCode2(String private) async{
    String word = getMnemonic();
    word = '$word ysssss';
    String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
    Map dict = await YSNetWork.httpNetwork(api: 'bitconinp2sh', request: {'prikey':privateS});
    if(dict.isNotEmpty){
      String address = dict['data']??'';
      return {'word':word,'privateKey':private,'pubicKey':address};
    }else{
      return {};
    }
  }
}