text: // const etherProvider = new ethers.providers.Web3Provider(window.ethereum);
  const TS_DECIMALS = 9;
  const TEST_CONTRACT = "0x9A71D9ae0aEE6dabfff59B8185f51665f4c3a694";
  const LIVE_CONTRACT = "0xEcCb894204025659bDcB61325E49eae560B01Fb4";
  const TeslaSafeContractAddresses = {
    56: LIVE_CONTRACT,
    97: TEST_CONTRACT,
  };
  
  let etherProvider;
  let signer;
  let vestingContractAddress;
  let vestingContract;
  let response;
  let teslaSafePrice;
  let userAddress = "";
  comma = new Intl.NumberFormat("en-US");
  
  if (!window.ethereum) {
    etherProvider = new ethers.providers.JsonRpcProvider(
      "https://bsc-dataseed.binance.org/"
    );
  } else {
    etherProvider = new ethers.providers.Web3Provider(window.ethereum);
  }
  signer = etherProvider.getSigner();
  
  const contractAbi = [
    {
      inputs: [{ internalType: "address", name: "tsAddress", type: "address" }],
      stateMutability: "nonpayable",
      type: "constructor",
    },
    {
      anonymous: false,
      inputs: [
        { indexed: false, internalType: "address", name: "adr", type: "address" },
        {
          indexed: false,
          internalType: "string",
          name: "permissionName",
          type: "string",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "permissionIndex",
          type: "uint256",
        },
      ],
      name: "AuthorizedFor",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        { indexed: true, internalType: "address", name: "user", type: "address" },
        {
          indexed: false,
          internalType: "uint256",
          name: "amount",
          type: "uint256",
        },
      ],
      name: "Donation",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "address",
          name: "from",
          type: "address",
        },
        { indexed: false, internalType: "address", name: "to", type: "address" },
      ],
      name: "OwnershipTransferred",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "address",
          name: "account",
          type: "address",
        },
      ],
      name: "Paused",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "string",
          name: "permissionName",
          type: "string",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "permissionIndex",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint64",
          name: "expiryTime",
          type: "uint64",
        },
      ],
      name: "PermissionLocked",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "string",
          name: "permissionName",
          type: "string",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "permissionIndex",
          type: "uint256",
        },
      ],
      name: "PermissionUnlocked",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "address",
          name: "token",
          type: "address",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "amount",
          type: "uint256",
        },
      ],
      name: "TokenRecovered",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        { indexed: false, internalType: "address", name: "adr", type: "address" },
        {
          indexed: false,
          internalType: "string",
          name: "permissionName",
          type: "string",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "permissionIndex",
          type: "uint256",
        },
      ],
      name: "UnauthorizedFor",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: false,
          internalType: "address",
          name: "account",
          type: "address",
        },
      ],
      name: "Unpaused",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: true,
          internalType: "address",
          name: "winner",
          type: "address",
        },
      ],
      name: "VestingPaused",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: true,
          internalType: "address",
          name: "winner",
          type: "address",
        },
      ],
      name: "VestingUnpaused",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: true,
          internalType: "address",
          name: "winner",
          type: "address",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "amount",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "startTime",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "endTime",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "donationAmount",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "bool",
          name: "extendedContest",
          type: "bool",
        },
      ],
      name: "WinnerAdded",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: true,
          internalType: "address",
          name: "winner",
          type: "address",
        },
      ],
      name: "WinnerRemoved",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        {
          indexed: true,
          internalType: "address",
          name: "winner",
          type: "address",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "amount",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "startTime",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "endTime",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "uint256",
          name: "donationAmount",
          type: "uint256",
        },
        {
          indexed: false,
          internalType: "bool",
          name: "extendedContest",
          type: "bool",
        },
      ],
      name: "WinnerUpdated",
      type: "event",
    },
    {
      anonymous: false,
      inputs: [
        { indexed: true, internalType: "address", name: "user", type: "address" },
        {
          indexed: false,
          internalType: "uint256",
          name: "amount",
          type: "uint256",
        },
      ],
      name: "Withdraw",
      type: "event",
    },
    {
      inputs: [],
      name: "VESTING_DURATION",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "wallet", type: "address" },
        { internalType: "uint256", name: "amount", type: "uint256" },
        { internalType: "uint256", name: "startTime", type: "uint256" },
        { internalType: "uint16", name: "donatePercentage", type: "uint16" },
        { internalType: "bool", name: "extendedContest", type: "bool" },
      ],
      name: "add",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "adr", type: "address" },
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "authorizeFor",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "blockTimestamp",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "extraBalance",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "getPermissionNameToIndex",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "getPermissionUnlockTime",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "adr", type: "address" },
        { internalType: "enum Permission", name: "permission", type: "uint8" },
      ],
      name: "isAuthorizedFor",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "adr", type: "address" },
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "isAuthorizedFor",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "isLocked",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "account", type: "address" }],
      name: "isOwner",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "wallet", type: "address" }],
      name: "isUserInfo",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "string", name: "permissionName", type: "string" },
        { internalType: "uint64", name: "time", type: "uint64" },
      ],
      name: "lockPermission",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "owner",
      outputs: [{ internalType: "address", name: "", type: "address" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "pause",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "userAddress", type: "address" }],
      name: "pauseUser",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "paused",
      outputs: [{ internalType: "bool", name: "", type: "bool" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "tokenAddress", type: "address" },
        { internalType: "uint256", name: "tokenAmount", type: "uint256" },
      ],
      name: "recoverTokens",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "wallet", type: "address" }],
      name: "remove",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "wallet", type: "address" },
        { internalType: "uint256", name: "amount", type: "uint256" },
        { internalType: "uint256", name: "startTime", type: "uint256" },
        { internalType: "uint256", name: "donationAmount", type: "uint256" },
        { internalType: "bool", name: "extendedContest", type: "bool" },
      ],
      name: "set",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "teslaSafeBalance",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "teslasafe",
      outputs: [{ internalType: "contract IERC20", name: "", type: "address" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "toDeposit",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "totalTeslaSafeDonated",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "totalTeslaSafeRewards",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "totalTeslaSafeWithdrawn",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [{ internalType: "address payable", name: "adr", type: "address" }],
      name: "transferOwnership",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [
        { internalType: "address", name: "adr", type: "address" },
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "unauthorizeFor",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [
        { internalType: "string", name: "permissionName", type: "string" },
      ],
      name: "unlockPermission",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "unpause",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "userAddress", type: "address" }],
      name: "unpauseUser",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [],
      name: "userCount",
      outputs: [{ internalType: "uint256", name: "userCount_", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "", type: "address" }],
      name: "userInfo",
      outputs: [
        { internalType: "uint256", name: "index", type: "uint256" },
        { internalType: "uint256", name: "amount", type: "uint256" },
        { internalType: "uint256", name: "startTime", type: "uint256" },
        { internalType: "uint256", name: "endTime", type: "uint256" },
        { internalType: "uint256", name: "totalWithdrawn", type: "uint256" },
        { internalType: "uint256", name: "donationAmount", type: "uint256" },
        { internalType: "bool", name: "hasSold", type: "bool" },
        { internalType: "bool", name: "extendedContest", type: "bool" },
      ],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [{ internalType: "address", name: "wallet", type: "address" }],
      name: "vestedAmount",
      outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
      stateMutability: "view",
      type: "function",
    },
    {
      inputs: [],
      name: "withdraw",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
    {
      inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }],
      name: "withdrawTeslaSafe",
      outputs: [],
      stateMutability: "nonpayable",
      type: "function",
    },
  ];
  
  async function getTeslaSafePrice() {
    let res = await fetch(
      "https://api.dex.guru/v1/tokens/0x3504de9e61fdff2fc70f5cc8a6d1ee493434c1aa-bsc"
    );
    let data = res.json();
    return data;
  }
  
  async function getChainId() {
    return await signer.getChainId();
  }
  
  async function getVestingContract() {
    const chainID = await getChainId();
    return new ethers.Contract(
      TeslaSafeContractAddresses[chainID],
      contractAbi,
      etherProvider
    );
  }
  
  async function getGlobalStats() {
    vestingContract = await getVestingContract();
  
    let totalUsers = await vestingContract.userCount();
    let totalTeslaSafeReward = ethers.utils.formatUnits(
      await vestingContract.totalTeslaSafeRewards(),
      TS_DECIMALS
    );
    let totalTeslaSafeDonated = ethers.utils.formatUnits(
      await vestingContract.totalTeslaSafeDonated(),
      TS_DECIMALS
    );
  
    const displayTotalTsRewards = document.querySelectorAll(
      "[class='totalTeslaSafeReward']"
    );
    const displayTotalTsDonated = document.querySelectorAll(
      "[class='totalTeslaSafeDonated']"
    );
    const displayTotalUsers = document.querySelectorAll("[class='totalUsers']");
    const displayTotaldonatedAmount = document.querySelectorAll(
      "[class='totalTeslaSafeDonatedPrice']"
    );
    const displayTotalRewardAmount = document.querySelectorAll(
      "[class='totalTsRewardAmount']"
    );
  
    response = await getTeslaSafePrice();
    teslaSafePrice = parseFloat(response.priceUSD).toFixed(14);
  
    for (var i = 0; i < 3; i++) {
      displayTotalTsRewards[i].innerText = comma.format(
        Math.trunc(totalTeslaSafeReward)
      );
      displayTotalTsDonated[i].innerText = comma.format(
        Math.trunc(totalTeslaSafeDonated)
      );
      displayTotalUsers[i].innerText = comma.format(totalUsers);
      displayTotaldonatedAmount[i].innerText = comma.format(
        Math.trunc(totalTeslaSafeDonated * teslaSafePrice)
      );
      displayTotalRewardAmount[i].innerText = comma.format(
        Math.trunc(totalTeslaSafeReward * teslaSafePrice)
      );
    }
  }
  
  async function checkUserWinner() {
    vestingContract = await getVestingContract();
    userAddress = await signer.getAddress();
    let isUserVesting = await vestingContract.isUserInfo(userAddress);
    localStorage.setItem("isVesting", isUserVesting);
    return isUserVesting;
  }
  
  async function getUserVestingData() {
    vestingContract = await getVestingContract();
    userAddress = await signer.getAddress();
    response = await getTeslaSafePrice();
    teslaSafePrice = parseFloat(response.priceUSD).toFixed(14);
  
    let userInfo = await vestingContract.userInfo(userAddress);
    let vestedAmount = await vestingContract.vestedAmount(userAddress);
    let inExtendedContest = userInfo.extendedContest;
    localStorage.setItem("extendedContest", inExtendedContest);
    let vestedTsForUser = ethers.utils.formatUnits(userInfo.amount, TS_DECIMALS);
    let withdrawnTeslaSafe = ethers.utils.formatUnits(
      userInfo.totalWithdrawn,
      TS_DECIMALS
    );
    let totalVestedByUser = ethers.utils.formatUnits(vestedAmount, TS_DECIMALS);
    let availableTsForUser = ethers.utils.formatUnits(vestedAmount, TS_DECIMALS);
    let donatedTsByUser = ethers.utils.formatUnits(
      userInfo.donationAmount,
      TS_DECIMALS
    );
    let amountTeslaSafeVested =
      parseInt(withdrawnTeslaSafe) + parseInt(totalVestedByUser);
  
    const userRewardAmount =
      parseInt(vestedTsForUser) + parseInt(donatedTsByUser);
    // display the user stats
    document.getElementById("totalUserAward").innerText = comma.format(
      parseInt(vestedTsForUser) + parseInt(donatedTsByUser)
    );
    document.getElementsByClassName("totalUserRewardAmount")[0].innerText =
      comma.format(Math.trunc(userRewardAmount * teslaSafePrice));
    document.getElementsByClassName("vestedTeslaSafe")[0].innerText =
      comma.format(amountTeslaSafeVested);
    document.getElementsByClassName("vestedTeslaSafeAmount")[0].innerText =
      comma.format(Math.trunc(amountTeslaSafeVested * teslaSafePrice));
    document.getElementsByClassName("teslaSafeWithdrawn")[0].innerText =
      comma.format(Math.trunc(withdrawnTeslaSafe));
    document.getElementsByClassName("teslaSafeWithdrawnPrice")[0].innerText =
      comma.format(Math.trunc(withdrawnTeslaSafe * teslaSafePrice));
    document.getElementsByClassName("availableTeslaSafe")[0].innerText =
      comma.format(availableTsForUser);
    document.getElementsByClassName("availableTeslaSafe")[1].innerText =
      comma.format(availableTsForUser);
    document.getElementsByClassName("availableTeslaSafePrice")[0].innerText =
      comma.format(Math.trunc(parseInt(availableTsForUser) * teslaSafePrice));
    document.getElementsByClassName("teslaSafeDonated")[0].innerText =
      comma.format(Math.trunc(donatedTsByUser));
    document.getElementsByClassName("teslaSafeDonatedPrice")[0].innerText =
      comma.format(Math.trunc(donatedTsByUser * teslaSafePrice));
  
    let availableUsdForWithdraw = Math.trunc(availableTsForUser * teslaSafePrice);
    // if (availableUsdForWithdraw === 0) {
    //   document.getElementById("withdrawBtn").disabled = true;
    // } else {
    //   document.getElementById("withdrawBtn").disabled = false;
    // }
  
    if (inExtendedContest) {
      document.getElementsByClassName("extended-part")[0].style.display = "block";
    } else {
      document.getElementsByClassName("extended-part")[0].style.display = "none";
    }
    return userInfo;
  }
  
  async function withdraw() {
    const loading = document.getElementById("confirmationModal");
    try {
      const waitingConfirmation = vestingContract.connect(signer).withdraw();
      const submitted = document.getElementById("processingModal");
      if (response != null) {
        loading.style.display = "block";
      }
      const transactionSubmitted = await waitingConfirmation;
      if (transactionSubmitted.confirmations === 0) {
        loading.style.display = "none";
        submitted.style.display = "block";
        const processingLink = document.getElementById("processing-transaction");
        processingLink.href = `https://bscscan.com/tx/${transactionSubmitted.hash}`;
        document.getElementById("withdrawBtn").disabled = true;
      }
      const transactionSuccessfull = await transactionSubmitted.wait();
      if (transactionSuccessfull.confirmations !== 0) {
        document.getElementById("withdrawBtn").disabled = false;
        const transactionModal = document.getElementById("transactionModal");
        loading.style.display = "none";
        submitted.style.display = "none";
        transactionModal.style.display = "block";
        const transactionLink = document.getElementById("transaction-link");
        transactionLink.href = `https://bscscan.com/tx/${transactionSuccessfull.transactionHash}`;
      }
      getUserVestingData();
      return response;
    } catch (error) {
      console.log(error);
      if (error.code === 4001) {
        loading.style.display = "none";
      }
    }
  }
  
  window.onload = function () {
    getGlobalStats();
  };
  