import { providers } from "ethers"
import { signLogin } from './utils.js'
import { apiPreRecharge } from "./../utils/request.js"
import { switchEthereumChain } from './utils.js'


export class BitgetWallet{
  constructor() {
    if (BitgetWallet.instance) {
      return BitgetWallet.instance;
    }
    BitgetWallet.instance = this;
    this._nativeProvider = window.bitkeep?.ethereum;
  }

  get nativeProvider() {
    return this._nativeProvider
  }

  async sendTransaction(provider, {from, to, data}) {
    const txHash = await provider.provider.request({
      method: 'eth_sendTransaction',
      params: [{
        from,
        to,
        data
      }]
    })
    // console.log(txHash)
    const res = await provider.waitForTransaction(txHash)
    if (res.status == 0) {
      throw new Error('transaction failed')
    }
    return txHash
  }

  async web3Provider() {
    const provider = new providers.Web3Provider(this.nativeProvider);
    const accounts = await this.nativeProvider.request({ method: "eth_requestAccounts" });
    return { provider, accounts };
  }

  async getAccessToken() {
    const accounts = await this.nativeProvider.request({ method: "eth_requestAccounts" });
    console.log(accounts)
    const { token, refreshToken } = await signLogin(this.nativeProvider, accounts[0]);
    return { token, refreshToken, accounts }
  }

  get installed() {
    // console.log('bitget install: ', window.bitkeep, window.bitkeep.ethereum)
    return !!window.bitkeep && !!window.bitkeep.ethereum;
  }

  // 充值
  async execBuyItem(data) {
    // await this.bc.checkPassportLogin();
    const token = localStorage.getItem('token')
    // const chainId = parseInt(import.meta.env.VUE_APP_NET_ID);
    // const subTitle = 'Choose a payment method to complete your purchase.'
    const provider = new providers.Web3Provider(this.nativeProvider);
    // const { provider, address } = await this.bc.selectAddress({subTitle: subTitle,targetChainId: chainId})
    const preDatas = {
      net_id: data.net_id,
      goods_id: data.goods_id,
      account_address: data.account_address,
      goods_num: data.goods_num,
      email: data.email,
    }
    // const token = this.bc.store.refreshToken
    // const { errocode, errmsg, calls } = await apiPreRecharge(preDatas, token)
    const { errocode, errmsg, calls } = await apiPreRecharge(data, token+'.cf')
    // console.log(res)
    // return
    if (errocode) {
      throw new Error(errmsg)
    }
    if (!calls || calls.length == 0) {
      throw new Error('no calls')
    }
    await this.checkAndChangeChain(data.net_id, provider)
    let resutls = []
    for (let i = 0; i < calls.length; i++) {
      const { to, data } = calls[i].trans_req
      let hash = await this.sendTransaction(provider, {from: data.account_address, to, data})
      resutls.push(hash)
    }
    return resutls
  }

  async logout() {
    // await this.nativeProvider.request({
    //   "method": "wallet_revokePermissions",
    //   "params": [
    //     {
    //       "eth_accounts": {}
    //     }
    //   ]
    // });
  }

  async getChainId() {
    const chainId = await this.nativeProvider.request({ method: "eth_chainId" });
    return parseInt(chainId);
  }

  async checkAndChangeChain(targetChainId, provider) {
    let chainId = await this.getChainId();
    if (chainId !== targetChainId) {
      console.log(`current chain: ${chainId}, want: ${targetChainId}`)
      chainId = await switchEthereumChain(provider.provider, targetChainId);
    }
  }
}