contract MTVXTokenPresaleBridge is Ownable {
    
    mapping (address => bool) public walletWhitelisted;
    mapping (address => uint256) public purchasedAmount;
    event TokensBought(uint256 tokenAmount, uint256 indexed ethAmount, address indexed sender);
    uint256 public tokensPerEth =  13333333*1e18;
    uint256 public maxEthAmount = 0.4 ether;
    uint256 public minEthAmount = 0.1 ether;
    uint256 public totalEthCap = 15 ether;
    uint256 public totalPurchasedAmount;
    bool public isInitialized = false;
    bool public isWhitelistPresale = false;
    address public tokenAddress;
    
    constructor() {
        address token = address(0x3505355aBC42683ed3114e3773190B646B77a1ba); // MTVX Token
        
        tokenAddress = token;
    }
    
    receive() external payable {
        buyTokens();
    }
    
    function buyTokens() payable public {
        require(isInitialized, "Private sale not active");
        if(isWhitelistPresale){
            require(walletWhitelisted[msg.sender], "User is not whitelisted");
        }
        require(msg.value > 0, "Must send ETH to get tokens");
        require(msg.value % minEthAmount == 0, "Must buy in increments of Minimum ETH Amount (0.1)");
        require(msg.value + purchasedAmount[msg.sender] <= maxEthAmount, "Cannot buy more than MaxETH Amount");
        require(msg.value + totalPurchasedAmount <= totalEthCap, "No more tokens available for presale");
        
        purchasedAmount[msg.sender] += msg.value;
        totalPurchasedAmount += msg.value;
        
        uint256 tokenAmount = (msg.value * tokensPerEth)/1e18;
        
        IERC20 token = IERC20(tokenAddress);
        require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens on contract to send");
        token.transfer(msg.sender, tokenAmount);
        emit TokensBought(tokenAmount, msg.value, msg.sender);
    }
    
    function initialize() external onlyOwner {
        require(!isInitialized, "May not initialize contract again");
        // Exclude the pair from fees so that users don't get taxed when selling.
        isInitialized = true;
    }
    
    // only use in case of emergency
    function emergencyTokenAddressUpdate(address newToken) external onlyOwner{
        tokenAddress = newToken;
    }
    
    function updateMinEthAmount(uint256 newAmt) external onlyOwner{
        require(!isInitialized, "can't change the rules after presale starts");
        minEthAmount = newAmt;
        require(maxEthAmount >= minEthAmount, "can't set the max lower than the min");
    }
    
    function updateMaxEthAmount(uint256 newAmt) external onlyOwner{
        require(!isInitialized, "can't change the rules after presale starts");
        maxEthAmount = newAmt;
        require(maxEthAmount >= minEthAmount, "can't set the max lower than the min");
    }
    
    function updateTotalCap(uint256 newCap) external onlyOwner{
        require(!isInitialized, "can't change the rules after presale starts");
        totalEthCap = newCap;
    }
    
    function setWhiteListPresale(bool isWhitelist) external onlyOwner {
        isWhitelistPresale = isWhitelist;
    }
    
    // only use in case of emergency or after presale is over
    function emergencyWithdrawTokens() external onlyOwner {
        IERC20(tokenAddress).transfer(msg.sender, IERC20(tokenAddress).balanceOf(address(this)));
    }
    
    function whitelistWallet(address wallet, bool value) public onlyOwner {
        walletWhitelisted[wallet] = value;
    }
    
    function whitelistWallets(address[] memory wallets) public onlyOwner {
        for(uint256 i = 0; i < wallets.length; i++){
            whitelistWallet(wallets[i], true);
        }
    }
    
    // owner can withdraw ETH after people get tokens
    function withdrawETH() external onlyOwner {
        (bool success,) = msg.sender.call{value: address(this).balance}("");
        require(success, "Withdrawal was not successful");
    }
}
function emergencyTokenAddressUpdate(address newToken) external onlyOwner{
    tokenAddress = newToken;
}

// only use in case of emergency