contract MooseTrax is ERC20, Ownable {
    IMetaMooseMansion public MetaMooseMansion;

    uint256 public constant BASE_RATE = 10000000000000000000; //10 Trax
    uint256 public START;
    bool rewardPaused = false;

    mapping(address => uint256) public rewards;
    mapping(address => uint256) public lastUpdate;
    mapping(address => bool) public allowedAddresses;

    event RewardPaid(address indexed user, uint256 reward);
    event RewardPaidForStaking(address indexed user, uint256 reward);

    constructor(address _metaMooseMansion) ERC20("Moose Trax", "TRAX") {
        MetaMooseMansion = IMetaMooseMansion(_metaMooseMansion);
        START = block.timestamp;
    }

    //pause reward if unpaused, unpause if paused.
    //false = paused; true = unpaused.
    function flipReward() external onlyOwner {
        rewardPaused = !rewardPaused;
    }

    function updateReward(address from, address to) external {
        require(
            msg.sender == address(MetaMooseMansion),
            "Caller not authorized"
        );
        if (from != address(0)) {
            rewards[from] += getPendingReward(from);
            lastUpdate[from] = block.timestamp;
        }
        if (to != address(0)) {
            rewards[to] += getPendingReward(to);
            lastUpdate[to] = block.timestamp;
        }
    }

    function claimReward() external {
        require(rewardPaused, "Claiming reward has been paused");
        address user = msg.sender;
        uint256 reward = rewards[user] + getPendingReward(user);
        if (reward > 0) {
            rewards[user] = 0;
            lastUpdate[user] = block.timestamp;
            _mint(user, reward);
            emit RewardPaid(user, reward);
        }
    }

    function claimByMetaMoose(address _user, uint256 _rewardAmount) external {
        require(rewardPaused, "Claiming reward has been paused");
        require(
            msg.sender == address(MetaMooseMansion),
            "Caller not authorized"
        );

        rewards[msg.sender] -= _rewardAmount;
        lastUpdate[msg.sender] = block.timestamp;
        _mint(_user, _rewardAmount);
        emit RewardPaidForStaking(_user, _rewardAmount);
    }

    function getTotalClaimable(address user) external view returns (uint256) {
        return rewards[user] + getPendingReward(user);
    }

    function getPendingReward(address user) internal view returns (uint256) {
        return
            (MetaMooseMansion.balanceOf(user) *
                BASE_RATE *
                (block.timestamp -
                    (lastUpdate[user] >= START ? lastUpdate[user] : START))) /
            86400;
    }

    function burn(address user, uint256 amount) external {
        require(
            allowedAddresses[msg.sender],
            "Address does not have permission to burn"
        );
        _burn(user, amount);
    }

    function setAllowedAddresses(address _address, bool _access)
        external
        onlyOwner
    {
        allowedAddresses[_address] = _access;
    }
}
function flipReward() external onlyOwner {
    rewardPaused = !rewardPaused;
}

//pause reward if unpaused, unpause if paused.
//false = paused; true = unpaused.