import 'dart:math';
import 'package:bs58check/bs58check.dart' as bs58check;
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_wallet/tools/YSAes.dart';
import 'package:flutter_wallet/tools/YSNetWork.dart';
import 'package:flutter_wallet/tools/YSSqflite.dart';
import 'package:flutter_wallet/tools/YSTools.dart';
import 'package:hex/hex.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:web3dart/web3dart.dart';



class YSTron{


  static String changeAddress(String str) {
    var bytes = bs58check.base58.decode(str);
    String value = HEX.encode(bytes.sublist(0, bytes.length - 4));
    // LogUtil.d('changeAddress======$value');
    return value;
  }

  static getBalance(String str) async{
    String address = changeAddress(str);
    var yourQuickNodeRpcUrl = YSData().rpc;
    var headers = {
      'Content-Type': 'application/json',
    };
    var body = jsonEncode({
      "jsonrpc": "2.0",
      "id": 1,
      "method": "eth_getBalance",
      "params": [address, "latest"]
    });
    var response = await http.post(
      Uri.parse(yourQuickNodeRpcUrl),
      headers: headers,
      body: body,
    );
    if (response.statusCode == 200) {
      var result = jsonDecode(response.body);
      String resultStr = '${result['result']}';
      var balance = int.parse(resultStr.replaceAll('0x', ''), radix: 16);
      String balanceStr = '${balance/pow(10, 6)}';
      LogUtil.d('TRON============$balanceStr');
      return balanceStr;
    }
  }


  static Future<String> transferData(BuildContext context,{required String from,required String to,required String private,required String amount}) async{
    // 创建一个新的HTTP客户端
    var client = http.Client();

    try {
    // 构建请求URL
    var url = Uri.parse('https://api.trongrid.io/wallet/createtransaction');
    // LogUtil.d('transferData3========$amount');
    // 构建请求参数
    var body = jsonEncode({
      'to_address': to,  // 替换为接收者的地址
      'owner_address': from,  // 替换为你的地址
      'amount': int.parse('${(double.parse(amount)*pow(10, 6))~/1}'),  // 转账金额（单位：TRX）
      "visible": true
    });
    LogUtil.d('transferData3=======1$body');
    YSFileWriteRead().writeContent(body.toString());
    // 发送POST请求
    var response = await client.post(
      url,
      headers: {'Content-Type': 'application/json','TRON-PRO-API-KEY' : '6c8142d8-877d-474d-9a8c-60a533493c9f','accept': 'application/json'},
      body: body,
    );
    // 解析响应结果
    var result = jsonDecode(response.body);
    LogUtil.d('transferData3============$result');
    YSFileWriteRead().writeContent(result.toString());
    Map request = {};
    request['tx'] = result;
    String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
    request['prikey'] = privateS;
    // ignore: use_build_context_synchronously
    Map dict = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tronsign', parameter: request);
    if(dict.isNotEmpty){
      // return false;
      Map data = dict['data'];
      result['signature'] = data['signature'];
      // 广播交易
      url = Uri.parse('https://api.trongrid.io/wallet/broadcasttransaction');
      LogUtil.d('transferData3============$result');
      YSFileWriteRead().writeContent(result.toString());
      response = await client.post(
        url,
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode(result),
      );
      // LogUtil.d('TRON============Transaction ID $result');
      // return;
      // 解析响应结果
      result = jsonDecode(response.body);
      LogUtil.d('transferData3============4${result['txid']}');
      YSFileWriteRead().writeContent(result.toString());
      if(result['result']==true){
        return result['txid']??'';
      }else{
        return '';
      }
    }else{
      return '';
    }
    } finally {
      // 关闭HTTP客户端
      client.close();
    }
  }

  static Future<String> transferContractData(BuildContext context,{
    required String from,
    required String to,
    required String private,
    required String amount,
    required String tokenId,
    required String tokenAddress
  }) async{
    var client = http.Client();

    try {
      LogUtil.d('transferData3========');
      Map result = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'createtransfer', parameter: {
        'contractAddress':tokenAddress,
        'ownerAddress':from,
        'toAddress':to,
        'amount':int.parse('${(double.parse(amount)*pow(10, 6))~/1}')
      });
      if(result.isNotEmpty){
        Map data = result['data']??{};
        if(data.isNotEmpty){
          Map request = {};
          request['tx'] = data;
          String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
          request['prikey'] = privateS;
          // ignore: use_build_context_synchronously
          Map dict = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tronsign', parameter: request);
          if(dict.isNotEmpty){
            // return '';
            Map data2 = dict['data'];
            data['signature'] = data2['signature'];
            // 广播交易
            var url = Uri.parse('https://api.trongrid.io/wallet/broadcasttransaction');
            LogUtil.d('transferData3=======$data');
            var response = await client.post(
              url,
              headers: {'Content-Type': 'application/json'},
              body: jsonEncode(data),
            );
            result = jsonDecode(response.body);
            LogUtil.d('transferData3============${response.body}');
            if(result['result']==true){
              return '${result['txid']??''}';
            }else{
              return '';
            }
          }else{
            return '';
          }
        }
      }
      return '';
    } finally {
      // 关闭HTTP客户端
      client.close();
    }
  }

  static Future<String> approveContractData(BuildContext context,{
    required String from,
    required String to,
    required String private,
    required String amount,
    required String fromTokenAddress,
    required String toTokenAddress
  }) async{
    var client = http.Client();

    try {
      // YSTronTable ysTronTable = YSTronTable().init();
      // ysTronTable.rawInsert(from_addr: from, to_addr: to, from_token_addr: fromTokenAddress,
      //     to_token_addr: toTokenAddress, amount: '100', hash: 'result3Data');
      // return '';
      LogUtil.d('transferData3========');
      int amountValue = double.parse(amount)~/1;
      String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
      Map result = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tron/myres', parameter: {
        'owner_address': from,
      });
      if(result.isNotEmpty){
        Map resultData = result['data'];
        int network_rate = resultData['network_rate'];
        int rest_energy = resultData['rest_energy'];
        // return '';
        // ignore: use_build_context_synchronously
        Map result2 = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tron/query/approve', parameter: {
          "amount":amountValue,
          "from_token":fromTokenAddress,
          "owner_address":from
        });
        if(result2.isNotEmpty){
          int result2Data = result2['data'];
          // ignore: use_build_context_synchronously
          Map result3 = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tron/approve/start', parameter: {
            "prikey":privateS,
            "amount":amountValue,
            "from_token":fromTokenAddress,
            'limit':(result2Data*network_rate*1.1)~/1
          });
          if(result3.isNotEmpty){
            String result3Data = result3['data']??'';
            YSTronTable ysTronTable = YSTronTable().init();
            ysTronTable.rawInsert(from_addr: from, to_addr: to, from_token_addr: fromTokenAddress,to_token_addr: toTokenAddress, amount: '$amountValue', hash: result3Data);
            return result3Data;
            // return result3Data;
            // ignore: use_build_context_synchronously
            // Map result4 = await YSNetWork.ysRequestHttpNOSet2(context, type: RequestType.post, api: 'tron/approve/check', parameter: {
            //   "hash":result3Data,
            // });
            // if(result4.isNotEmpty){
            //   Map result4Data = result4['data']??{};
            //   if(result4Data.isNotEmpty){
            //     // ignore: use_build_context_synchronously
            //     Map result5 = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tron/query/swap', parameter: {
            //       "amount":amountValue                                       //转账金额 要和授权的保持一致
            //       ,"from_token":fromTokenAddress     //转出token
            //       ,"to_token":toTokenAddress        //转入token
            //       ,"owner_address":from   //钱包地址
            //     });
            //     if(result5.isNotEmpty){
            //
            //     }
            //   }
            // }
          }
        }
      }
      return '';
      if(result.isNotEmpty){
        Map data = result['data']??{};
        if(data.isNotEmpty){
          Map request = {};
          request['tx'] = data;
          String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
          request['prikey'] = privateS;
          // ignore: use_build_context_synchronously
          Map dict = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tronsign', parameter: request);
          if(dict.isNotEmpty){
            // return '';
            Map data2 = dict['data'];
            data['signature'] = data2['signature'];
            // 广播交易
            var url = Uri.parse('https://api.trongrid.io/wallet/broadcasttransaction');
            LogUtil.d('transferData3=======$data');
            var response = await client.post(
              url,
              headers: {'Content-Type': 'application/json'},
              body: jsonEncode(data),
            );
            result = jsonDecode(response.body);
            LogUtil.d('transferData3============${response.body}');
            if(result['result']==true){
              return '${result['txid']??''}';
            }else{
              return '';
            }
          }else{
            return '';
          }
        }
      }
      return '';
    } finally {
      // 关闭HTTP客户端
      client.close();
    }
  }

  static Future<String> exchangeContractData2(BuildContext context,{
    required String from,
    required String to,
    required String private,
    required String amount,
    required String tokenAddress
  }) async{
    var client = http.Client();

    try {
      // 构建交易请求
      Map<String, dynamic> requestBody = {
        'privateKey': private,
        'owner_address': from,
        'to_address': tokenAddress,
        'contractAddress': tokenAddress,
        'amount': double.parse(amount)~/1,
        'visible':true
      };
      LogUtil.d(requestBody);
      // 发送交易请求
      final response = await http.post(
        Uri.parse('https://api.trongrid.io/wallet/createtransaction'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(requestBody),
      );
      LogUtil.d(response.body);
      return '';
      // 解析交易结果
      if (response.statusCode == 200) {
        Map<String, dynamic> responseBody = jsonDecode(response.body);
        Map request = {};
        request['tx'] = responseBody;
        String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
        request['prikey'] = privateS;
        // ignore: use_build_context_synchronously
        Map dict = await YSNetWork.ysRequestHttpNOSet(context, type: RequestType.post, api: 'tronsign', parameter: request);
        if(dict.isNotEmpty){
          // return '';
          Map data2 = dict['data'];
          responseBody['signature'] = data2['signature'];
          // 广播交易
          var url = Uri.parse('https://api.trongrid.io/wallet/broadcasttransaction');
          LogUtil.d('transferData3=======$responseBody');
          var response = await client.post(
            url,
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode(responseBody),
          );
          Map result = jsonDecode(response.body);
          LogUtil.d('transferData3============${response.body}');
          if(result['result']==true){
            return '${result['txid']??''}';
          }else{
            return '';
          }
        }
        // String transactionId = responseBody['txID'];
        // LogUtil.d('Transaction ID: $transactionId');
      } else {
        LogUtil.d('Transaction failed with status code: ${response.statusCode}');
      }
      return '';
    } finally {
      // 关闭HTTP客户端
      client.close();
    }
  }

  /// 将合约格式化
  static Future<DeployedContract> fromAssets(String path, String contractAddress) async {
    final contractJson = jsonDecode(await rootBundle.loadString(path));
    DeployedContract value = DeployedContract(ContractAbi.fromJson(jsonEncode(contractJson['abi']),contractJson['contractName'] as String),EthereumAddress.fromHex(contractAddress));
    return value;
  }

}

String toHex(Uint8List bytes) {
  return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
}