import WalletConnect from '@walletconnect/client';
import QRCodeModal from '@walletconnect/qrcode-modal';
import {ElLoading} from 'element-plus';

// interface State {
//   connector: WalletConnect | null;
//   fetching: boolean;
//   connected: boolean;
//   chainId: number;
//   showModal: boolean;
//   pendingRequest: boolean;
//   uri: string;
//   accounts: string[];
//   address: string;
//   result: any | null;
//   assets: IAssetData[];
// }
const state: any = {
  connector: null,
  fetching: false,
  connected: false,
  chainId: 1,
  showModal: false,
  pendingRequest: false,
  uri: '',
  accounts: [],
  address: '',
  result: null,
  assets: [],
};

export function getState() {
  return state;
}

export function walletConnect(kill = false, autoCreate = false) {
  return new Promise(async (r, e) => {

    // bridge url
    const bridge = 'https://bridge.walletconnect.org';

    if (!state.connector) {
      // create new connector
      state.connector = new WalletConnect({bridge, qrcodeModal: QRCodeModal});
      state.connector.on('session_update', async (error: any, payload: any) => {
        console.log(`connector.on("session_update")`, error, payload);

        if (error) {
          throw error;
        }

        const {chainId, accounts} = payload.params[0];
        _onSessionUpdate(accounts, chainId);
      });

      state.connector.on('connect', (error: any, payload: any) => {
        console.log(`connector.on("connect")`, error, payload);

        if (error) {
          e();
          throw error;
        }
        _onConnect(payload);
        r();
      });

      state.connector.on('disconnect', (error: any, payload: any) => {
        console.log(`connector.on("disconnect")`, error, payload);

        if (error) {
          throw error;
        }

        _onDisconnect();
      });
    }

    kill && state.connector.connected && (await state.connector.killSession());

    if (state.connector.connected) {
      const {chainId, accounts} = state.connector;
      const address = accounts[0];
      Object.assign(state, {
        connected: true,
        chainId,
        accounts,
        address,
      });
      r();
    } else if (autoCreate) {
      // create new session
      await state.connector.createSession();
    }
  });
}

async function _onDisconnect() {
  killSession();
}

async function _onConnect(payload: any) {
  const {chainId, accounts} = payload.params[0];
  const address = accounts[0];
  Object.assign(state, {
    connected: true,
    chainId,
    accounts,
    address,
  });
}

async function _onSessionUpdate(accounts: any, chainId: any) {
  const address = accounts[0];
  Object.assign(state, {chainId, accounts, address});
}

function _reset() {
  state.connector = null;
  state.fetching = false;
  state.connected = false;
  state.chainId = 1;
  state.showModal = false;
  state.pendingRequest = false;
  state.uri = '';
  state.accounts = [];
  state.address = '';
  state.result = null;
  state.assets = [];
}

export function killSession() {
  const {connector} = state;
  if (connector) {
    connector.killSession();
  }
  _reset();
}

export async function walletConnectSign(data: any) {
  const {connector} = state;
  if (!connector || !connector.connected) {
    await walletConnect(false, true);
  }
  const loading = ElLoading.service({
    lock: true,
    text: '请在手机上同意签名请求...',
    background: 'rgba(0, 0, 0, 0.7)',
  });

  try {
    var sign = await state.connector.signPersonalMessage([data, state.address.toLowerCase()]);
    loading.close();
    return sign;
  } catch (e) {
    console.log(e);
    loading.close();
  }
}
