import { useCallback, useEffect, useState } from 'react';
import { useSDK } from '@metamask/sdk-react';
import { Web3 } from 'web3';
import Button from 'react-bootstrap/Button';
// import './App.css';
import DAOArtifact from './assets/DAO.json';
import work1Artifact from './assets/Work1.json';

const DAOAddress = '0x91ffddC013E2Df43E8FB177922d762bC8D776e79';
const work1Address = '0x08673dE03e1e9b4c9A0aF99463fa4DEFD3891987';

function App() {
  const {
    sdk, connected, provider, chainId, account, balance,
  } = useSDK();

  const [work1, setWork1] = useState();
  const [DAO, setDAO] = useState();
  const [work1Price, setWork1Price] = useState();
  const [balanceEther, setBalanceEther] = useState();
  const [reputation, setReputation] = useState();
  const [validationPoolCount, setValidationPoolCount] = useState();
  const [latestPoolIndex, setLatestPoolIndex] = useState();
  const [votePasses, setVotePasses] = useState();

  const watchReputationNFT = useCallback(async (tokenId) => {
    await provider.request({
      method: 'wallet_watchAsset',
      params: {
        type: 'ERC721',
        options: {
          address: DAOAddress,
          tokenId: BigInt(tokenId).toString(),
        },
      },
    });
  }, [provider]);

  useEffect(() => {
    if (!provider) return;
    const web3 = new Web3(provider);
    const work1Contract = new web3.eth.Contract(work1Artifact.abi, work1Address);
    const DAOContract = new web3.eth.Contract(DAOArtifact.abi, DAOAddress);

    const fetchPrice = async () => {
      const priceWei = await work1Contract.methods.price().call();
      setWork1Price(web3.utils.fromWei(priceWei, 'ether'));
    };
    const fetchReputation = async () => {
      setReputation(await DAOContract.methods.valueOf(0).call());
    };

    const fetchValidationPoolCount = async () => {
      setValidationPoolCount(await DAOContract.methods.validationPoolCount().call());
    };

    fetchPrice();
    fetchReputation();
    fetchValidationPoolCount();
    setWork1(work1Contract);
    setDAO(DAOContract);

    DAOContract.events.ValidationPoolInitiated({ fromBlock: 'latest' }).on('data', (event) => {
      console.log('event: validation pool initiated', event);
      setLatestPoolIndex(event.returnValues.poolIndex);
      fetchValidationPoolCount();
    });

    DAOContract.events.ValidationPoolResolved({ fromBlock: 'latest' }).on('data', (event) => {
      console.log('event: validation pool resolved', event);
      setVotePasses(event.returnValues.votePasses);
      if (event.returnValues.votePasses) {
        watchReputationNFT(event.returnValues.newTokenId);
      }
    });
  }, [provider, watchReputationNFT]);

  useEffect(() => {
    if (provider && balance) {
      const web3 = new Web3(provider);
      setBalanceEther(web3.utils.fromWei(balance, 'ether'));
    }
  }, [provider, balance]);

  const connect = async () => {
    try {
      await sdk?.connect();
    } catch (err) {
      console.warn('failed to connect..', err);
    }
  };

  const disconnect = async () => {
    try {
      sdk?.terminate();
    } catch (err) {
      console.warn('failed to disconnect..', err);
    }
  };

  const initiateValidationPool = async () => {
    const poolDuration = 0;
    await DAO.methods.initiateValidationPool(account, poolDuration).send({
      from: account,
      gas: 1000000,
      value: 100,
    });
  };

  const evaluateOutcome = async () => {
    await DAO.methods.evaluateOutcome(latestPoolIndex).send({
      from: account,
      gas: 1000000,
    });
  };

  // const stakeAvailability = async () => { }

  // const requestWork = async () => {
  //   work1.events.WorkAssigned(() => {
  //     console.log('event callback');
  //   });
  //   await work1.methods.requestWork().send({
  //     from: account,
  //     gas: 1000000,
  //   });
  // };

  return (
    <>
      {!connected && <Button onClick={() => connect()}>Connect</Button>}

      {connected && (
        <>
          <div>
            <div>
              {chainId && `Chain ID: ${chainId}`}
            </div>
            <div>
              {`Account: ${account}`}
            </div>
            <div>
              {`Balance: ${balanceEther} ETH`}
            </div>
            <div>
              {`REP: ${reputation}`}
            </div>
            <Button onClick={() => disconnect()}>Disconnect</Button>
          </div>
          <div>
            {`Validation Pool Count: ${validationPoolCount}`}
          </div>
          <div>
            <Button onClick={() => initiateValidationPool()}>Initiate Validation Pool</Button>
          </div>
          <div>
            <Button onClick={() => evaluateOutcome()}>Evaluate Outcome</Button>
          </div>
          <div>
            {`Outcome: ${votePasses}`}
          </div>
          <div>
            {`Work1 Price: ${work1Price} ETH`}
          </div>
          <div>
            { /* <Button onClick={() => requestWork()}>Request Work</Button> */ }
          </div>
        </>
      )}
    </>
  );
}

export default App;
