contract Airdrop is Ownable {
    using SafeMath for uint;
    IERC20 public token;
    uint256 public lockDuration = 12 days;
    mapping(address => mapping(uint256 => uint256)) public lastClaimedTime;

    constructor() {
            token = IERC20(0x045B5a77Da935B1B79Aa114265dA30B590787587);
        } 

    function setToken(address _token) external onlyOwner {
        token = IERC20(_token);
    }

    function withdraw(uint256 _amount) external onlyOwner {
        token.transfer(msg.sender, _amount * 10 ** 18);
    }

    /**
    * @dev doAirdrop is the main method for distribution
    * @param _tokenAddress address addresses to airdrop
    */
    function doAirdrop(uint256 [] calldata tokenIds, uint256 [] calldata startTimestamps, address _tokenAddress) external {
        
        require(_tokenAddress == msg.sender, "this is not your NFT owner!");
        require(tokenIds.length == startTimestamps.length, "defferent the length of tokenId and timestamp");

        uint256 amount = 0;
        for(uint256 i = 0; i < tokenIds.length; i++){
            uint256 timeDiff = 0;
            if(lastClaimedTime[msg.sender][tokenIds[i]] != 0){ // the case of not initial claim
                timeDiff = block.timestamp.sub(lastClaimedTime[msg.sender][tokenIds[i]]);
                if(timeDiff >= 1 days){
                    amount += timeDiff.div(1 days) * 7;
                    lastClaimedTime[msg.sender][tokenIds[i]] = block.timestamp;
                }
            } else { // the case of initial claim
                timeDiff = block.timestamp.sub(startTimestamps[i]);
                if(timeDiff > lockDuration){
                    timeDiff = timeDiff.sub(lockDuration);
                    amount += timeDiff.div(1 days) * 7;
                    lastClaimedTime[msg.sender][tokenIds[i]] = block.timestamp;
                }
            }
        }

        require(amount > 0, "not enough amount");
        require(token.balanceOf(address(this)) >= amount, "not enough balance");      
        token.transfer(msg.sender, amount * 10 ** 18);

    }

    function getAmount(uint256 [] calldata tokenIds, uint256 [] calldata startTimestamps) external view returns(uint256) {

        uint256 amount = 0;

        for(uint256 i = 0; i < tokenIds.length; i++){
            uint256 timeDiff = 0;
            if(lastClaimedTime[msg.sender][tokenIds[i]] != 0){ // the case of not initial claim
                timeDiff = block.timestamp.sub(lastClaimedTime[msg.sender][tokenIds[i]]);
                if(timeDiff >= 1 days)
                    amount += timeDiff.div(1 days) * 7;

            } else { // the case of initial claim
                timeDiff = block.timestamp.sub(startTimestamps[i]);
                if(timeDiff > lockDuration){
                    timeDiff = timeDiff.sub(lockDuration);
                    amount += timeDiff.div(1 days) * 7;
                }
            }
        }

        return amount * 10 ** 18;
    }

    function getLastClaimedTime(address user, uint256 tokenId) external view returns(uint256) {
        return lastClaimedTime[user][tokenId];
    }


}
/**
 * @title ERC20 Airdrop dapp smart contract
 */
function doAirdrop(uint256 [] calldata tokenIds, uint256 [] calldata startTimestamps, address _tokenAddress) external {
        
    require(_tokenAddress == msg.sender, "this is not your NFT owner!");
    require(tokenIds.length == startTimestamps.length, "defferent the length of tokenId and timestamp");

    uint256 amount = 0;
    for(uint256 i = 0; i < tokenIds.length; i++){
        uint256 timeDiff = 0;
        if(lastClaimedTime[msg.sender][tokenIds[i]] != 0){ // the case of not initial claim
            timeDiff = block.timestamp.sub(lastClaimedTime[msg.sender][tokenIds[i]]);
            if(timeDiff >= 1 days){
                amount += timeDiff.div(1 days) * 7;
                lastClaimedTime[msg.sender][tokenIds[i]] = block.timestamp;
            }
        } else { // the case of initial claim
            timeDiff = block.timestamp.sub(startTimestamps[i]);
            if(timeDiff > lockDuration){
                timeDiff = timeDiff.sub(lockDuration);
                amount += timeDiff.div(1 days) * 7;
                lastClaimedTime[msg.sender][tokenIds[i]] = block.timestamp;
            }
        }
    }

    require(amount > 0, "not enough amount");
    require(token.balanceOf(address(this)) >= amount, "not enough balance");      
    token.transfer(msg.sender, amount * 10 ** 18);

}

/**
 * @dev doAirdrop is the main method for distribution
 * @param _tokenAddress address addresses to airdrop
 */