
import Web3 from 'web3';

export function createWeb3() {
    return (dispatch) => {
        dispatch({type: 'CREATE_WEB3_STARTED'});
        try {
            let web3;
            if(window.ethereum) {
                web3 = new Web3(window.ethereum);
                window.ethereum.enable();
            } else if(window.web3) {
                web3 = new Web3(window.web3.currentProvider);
            }
            if(web3) {
                dispatch({type: 'CREATE_WEB3_SUCCEEDED', web3});
            } else {
                throw new Error('CREATE_WEB3_FAILED');
            }
        } catch(error) {
            dispatch({type: 'CREATE_WEB3_FAILED', error});
        }
    }
}

export function createContract(address, abi, web3) {
    return (dispatch) => {
        dispatch({type: 'CREATE_CONTRACT_STARTED'});
        try {
            const contract = new web3.eth.Contract(abi, address);
            if(contract) {
                dispatch({type: 'CREATE_CONTRACT_SUCCEEDED', contract});
            } else {
                dispatch({type: 'CREATE_CONTRACT_FAILED', error: { message: 'CREATE_CONTRACT_FAILED'}});
            }
        } catch(error) {
            dispatch({type: 'CREATE_CONTRACT_FAILED', error});
        }
    }
}

export function connectWallet(web3, contract) {
    return (dispatch) => {
        dispatch({type: 'CONNECT_WALLET_STARTED'});
        dispatch({type: 'SET_WALLET_ADDRESS_STARTED'});
        let account;
        try {
            if(web3) {
                web3.eth.getAccounts().then((res) => {
                    account = res[0];
                    if(account) {
                        dispatch(getTokenBalance(account, contract));
                        dispatch({type: 'CONNECT_WALLET_SUCCEEDED', account});
                    } else {
                        dispatch({type: 'CONNECT_WALLET_FAILED', error: {message: 'CONNECT_WALLET_FAILED'}});
                    }
                });
            }
        } catch(error) {
            dispatch({type: 'CONNECT_WALLET_FAILED', error});
        }
    }
}

export function getTokenBalance(address, contract) {
    return (dispatch) => {
        dispatch({type: 'GET_BALANCE_STARTED'});
        contract.methods.balanceOf(address).call().then((balance) => {
            dispatch({type: 'GET_BALANCE_SUCCEEDED', balance});
        }).catch((error) => {
            dispatch({type: 'GET_BALANCE_FAILED', error});
        });
    }
}