import Web3 from 'web3';
import detectEthereumProvider from '@metamask/detect-provider';
import { message } from 'antd';
import BigNumber from 'bignumber.js';

let provider: any;

export const web3 = new Web3();
if (typeof window.ethereum !== 'undefined') {
  web3.eth.defaultAccount = window.ethereum.selectedAddress;
}

export async function initWeb3() {
  provider = await detectEthereumProvider();

  if (!provider) {
    console.log('请安装MetaMask');
    return false;
  }

  try {
    web3.setProvider(provider);
    const accounts = await provider.request({
      method: 'eth_requestAccounts',
    });
    web3.eth.defaultAccount = accounts[0];
    return true;
  } catch (reason) {
    switch (reason) {
      case 'Already processing eth_requestAccounts. Please wait.': // 已有请求存在
        message.warning('请打开MetaMask完成授权');
        break;
      case 'User rejected provider access': //如果用户拒绝了登录请求
        message.warning('请同意登录请求');
        break;
      default:
        // 本不该执行到这里，但是真到这里了，说明发生了意外
        message.warning('登录出错！err:' + reason);
        break;
    }
  }
  return false;
}

//发布合约
/**
 *
 * @param abi 合约ABI
 * @param bin 合约二进制
 */
export async function deployContract(abi: string, bin: string, params) {
  const contract = new web3.eth.Contract(eval('(' + abi + ')'));
  const result = await contract
    .deploy({
      data: '0x' + bin,
      arguments: params,
    })
    .send({ from: web3.eth.defaultAccount + '', gas: 3000000 }, async function (e, contract) {});
  return result._address;
}

// 代币转账
/**
 *
 * @param abi 合约ABI
 * @param address 合约地址
 * @param toAddress 转账地址
 */
export async function transfer(abi: string, address: string, toAddress: string) {
  const contract = new web3.eth.Contract(eval('(' + abi + ')'), address);
  await contract.methods
    .transfer(toAddress, new BigNumber(1 * Math.pow(10, 18)))
    .send({ from: web3.eth.defaultAccount }, function (error, transactionHash) {
      if (!error) {
        console.log('transactionHash is ' + transactionHash);
      } else {
        console.log(error);
      }
    });
}

// NFT创建
/**
 *
 * @param abi 合约ABI
 * @param address 合约地址
 * @param toAddress 转账地址
 */

export async function NFTMint(params: any) {
  if (params.toAddress == '' || params.toAddress == null || params.toAddress == undefined) {
    params.toAddress = web3.eth.defaultAccount;
  }
  let tx_hash = '';
  const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
  await contract.methods
    .Mint(params.toAddress)
    .send({ from: web3.eth.defaultAccount }, function (error, transactionHash) {
      if (!error) {
        tx_hash = transactionHash;
      } else {
        console.log(error);
      }
    });
  return tx_hash;
}

// NFT转移
/**
 *
 * @param abi 合约ABI
 * @param address 合约地址
 * @param toAddress 转账地址
 * @param token_id
 */
export async function transferNFT(params: any) {
  const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
  await contract.methods
    .safeTransferFrom(web3.eth.defaultAccount, params.toAddress, params.token_id)
    .send({ from: web3.eth.defaultAccount }),
    function (error, transactionHash) {
      if (!error) {
        return transactionHash;
      } else {
        console.log(error);
      }
    };
}

// NFT销毁
/**
 *
 * @param abi 合约ABI
 * @param address 合约地址
 * @param token_id
 */
export async function burnNFT(params: any) {
  const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
  await contract.methods.Burn(params.token_id).send({ from: web3.eth.defaultAccount }),
    function (error, transactionHash) {
      if (!error) {
        return transactionHash;
      } else {
        console.log(error);
      }
    };
}
