contract CryptoSigmaMales is ERC721, ERC721Enumerable, Pausable, Ownable {
    
    event BaseURIChanged(string newBaseURI);
    event SaleMint(address minter, uint256 count);
    event setSaleStartedChanged(bool newSaleStarted);

    uint256 public nextTokenId = 1;
    uint256 public mintRate = 99900000000000000;
    uint public max_supply = 3333;
    uint public tx_limit = 20;
    
    string public baseURI;
    bool public saleStarted;

    constructor() ERC721("CryptoSigmaMales", "CSM") {}

    function _baseURI() internal view override returns (string memory) {
        return baseURI;
    }
    
    function setSaleStarted(bool _saleStarted) external onlyOwner {
        saleStarted = _saleStarted;
        emit setSaleStartedChanged(_saleStarted);
    }

    
    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    function setBaseURI(string calldata newbaseURI) external onlyOwner {
        baseURI = newbaseURI;
        emit BaseURIChanged(newbaseURI);
    }
    
    function safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId);
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        whenNotPaused
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    // The following functions are overrides required by Solidity.

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
    
    function mintTokens(uint256 count) external payable {
       
        uint256 _nextTokenId = nextTokenId;
        require(saleStarted, "Sale has not started");
        require(count > 0 && count <= tx_limit, "Invalid count or limit exceeded");
        require(_nextTokenId + count <= max_supply, "Max supply exceeded");
        require(mintRate * count <= msg.value, "Incorrect Ether value");


        for (uint256 ind = 0; ind < count; ind++) {
            safeMint(msg.sender, _nextTokenId + ind);
        }
        nextTokenId += count;

        emit SaleMint(msg.sender, count);
    }
    
    function withdraw() public onlyOwner{
        require(address(this).balance > 0, "No Balance.");
        payable(owner()).transfer(address(this).balance);
    }
    
}
function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC721, ERC721Enumerable)
    returns (bool)
{
    return super.supportsInterface(interfaceId);
}

// The following functions are overrides required by Solidity.