contract HyNinja is
    ERC721,
    ERC721Enumerable,
    ERC721URIStorage,
    ERC721Burnable,
    Ownable
{
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;
    uint256 public MAX_NINJA_TOKENS = 1000;
    uint256 public mintPrice = 80000000000000000; // 0.08 ETH
    bool public saleIsActive = false;

    string public baseUri;
   string public NINJA_PROVENANCE;
    event SetBaseUri(string indexed baseUri);

    modifier whenSaleActive() {
        require(saleIsActive, "TheLostGlitches: Sale is not active");
        _;
    }

    constructor() ERC721("HyNinja", "NINJA") {}

    function safeMint(address to) public onlyOwner {
        _tokenIdCounter.increment();
        _safeMint(to, _tokenIdCounter.current());
    }

    function mint() external payable whenSaleActive {
        require(
            _tokenIdCounter.current() <= MAX_NINJA_TOKENS,
            "HyNinja: Max amount reached."
        );
        require(
            msg.value >= mintPrice,
            "HyNinja: Ether value sent is too low."
        );
        _tokenIdCounter.increment();
        _safeMint(msg.sender, _tokenIdCounter.current());
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    function toggleSaleState() external onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function setBaseUri(string memory _baseUri) external onlyOwner {
        baseUri = _baseUri;
        emit SetBaseUri(baseUri);
    }

    function setTokenURI(uint256 tokenId, string memory _tokenURI)
        external
        onlyOwner
    {
        super._setTokenURI(tokenId, _tokenURI);
    }

function setProvenanceHash(string memory provenanceHash_) external onlyOwner
 {   
     NINJA_PROVENANCE = provenanceHash_;
    }

    // The following functions are overrides required by Solidity.

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

    function _burn(uint256 tokenId)
        internal
        override(ERC721, ERC721URIStorage)
    {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
) internal override(ERC721, ERC721Enumerable) {
    super._beforeTokenTransfer(from, to, tokenId);
}

// The following functions are overrides required by Solidity.