// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 < 0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

/*
!!!!!!!!!!!!!???????????????7!!!!!!!!!!!!!!7???????JJJJ???7!!!!!!!!!!!!!!7???????????????!!!!!!!!!!!
!!!!!!!!!!!!!???????????????7!!!!!7JYYYYJ7!7?JJJY5GBBGPP5?7!!!!!!!!!!!!!!7???????????????!!!!!!!!!!!
!!!!!!!!!!!!!???????????????!!!!!?GGJ7!?PGJ?JY!7GBBGY77JGG55Y7!!!!!!!!!!!!???????????????!!!!!!!!!!!
77777777777777777777777777???7777PBP?~^75BB5GPY5BBBP?!!JPG7JGYYJJJYGBBBG5J77777777777777777777777777
?????????????!!!!!!!!!777YJJPY??JYBBP555PGGGP?!PBGPPPP5G##BBBBB5?5#BPYY5GB5!!!!!!!!!!!!!!???????????
?????????????!!!!!!!!JYYP5JYPJJ5GGGGGGGGGPPGPPGG5?!!?5BB#BBBB##BBG5Y?~^!YGB?!!!!!!!!!!!!!???????????
?????????????!!!!!!!!JY??5P5YJPBBPJ7!!7?Y5PPGGGPY?7?YP#BP555PPGBB#57Y??YPBG7!!!!!!!!!!!!!???????????
?????????????!!!!!!!!75J?5BY7P#BP7^...^75Y7?5GGBBBBBBBBY!^^~7?Y5PGBGGGGBBGGP5Y?!!!!!!!!!!???????????
?????????????!!!!!!JPB###BBBBB#BP?!~~!?YG5?J5P5YPGPPGBGJ!!J5PGGGGGPGGGBBGPY?JYGP7!!!!!!!!???????????
?????????????!!!!!P&#BG5J??J5G##BGP55PPGBBBBGP5JYJ.:?GBGGBG5J?JJY5PPPGGG5J7!!?P#5!!!!!!!!???????????
777777777777777775&#BGP5J!.^YBBBGGGBBB##BBBBBGPY?:.^7YG#BP?~..:~!?Y55PGGGGPPPBB#Y7777777777777777777
!!!!!!!!!!!!!????PBBBBBBBBPPGGGY77?5GBGP5GB&#BG5JJJYPB##B57~:^^!?Y5PGGGGGGBBBBGYJJ???????!!!!!!!!!!!
!!!!!!!!!!!!!????Y#BG5YY5PGGGBGJ~^!YGB??5BBJYBB####BBYY&BG5YY555PGBBBPJ!7JPGP55??5J??????!!!!!!!!!!!
!!!!!!!!!!!!!???JYBGJ!~!?5GGBGGPYY5G#BPGB5J775Y~~?55J. J#&B5?YPP55PGG5?~~?PBP7PPYYJ??????!!!!!!!!!!!
!!!!!!!!!!!!!??J5?YBP5Y5PGBGPYJJYPGBYJJG~.YJ!5G^  ..    ^JG##B#P?~?PGBPYY5PGBGGJ?????????!!!!!!!!!!!
!!!!!!!!!!!!!???Y5P5Y5YJ5GBP?~^!JPB#^:?5J^:7J?~            :^7555Y7^~GBG5J?J5GBP?????????!!!!!!!!!!!
!!!!!!!!!!!!!????YG?!JY?PBBG5JJYGB#P77~^?P?.               .77~~7P5~ G#GY7^^!5BBJ????????!!!!!!!!!!!
77777777777777777?Y55JJ5BBBGGBBB##Y7!~~!P5#5     .::::.    77~~~55BB~?##BPYJYGB5?7777777777777777777
?????????????!!!!!!!!7?JPB#B5JJYGP?!^^^JPG&#! .7Y55555Y?^ ^7^^^7PP#&G7?5GBBBBP?!!!!!!!!!!???????????
?????????????!!!!!!!75Y?5PPBGY?5G7!^:::5PB#&Y:PG55YYJJ?J5!!~:::JPG##BJ??7J5??!!!!!!!!!!!!???????????
?????????????!!!!!!!!?JYGY7J5YY555Y::::55##&YYB55Y?77!~7Y5?::::J5B##BG5J~?PY!!!!!!!!!!!!!???????????
?????????????!!!!!!!!!!!?P57?P5?Y57....J?G##J?B55Y?7777J5Y7: ..7J5##GJY5Y5P5YYYY7!!!!!!!!???????????
?????????????!!!!!!!!!!5BGY7?P5J?7J^...!?Y##~ ?P55YYJYY5J^^!...~JJB#PJ77J?J5JJ5P5!!!!7??7???????????
?????????????!!!!!!!!!J@#BY5BG~^::^!:..:J?PY:?!7JYYYYYJ7!7~7^...??5G~^~???5YJ55PP7!?YYY55Y??????????
??????77JYJ?7777777!!!Y@#BJY##7~^^::!^:.~J7. ..::::..:::.. .7!:.^JY~:!???J5YY5PPP?YY??Y5PY??????????
!!!!!!?GBB#BJ??????Y55G@#GJP&B!!!~^~77?5?^                   ^?5YJ?7!!!!!?5JY5PPPJ?JY5PP5!!!!!!!!!!!
!!!!!!B@BYYG&PYPYPG#GYG@&GYB&J!!!!!~!^^5^.....           .....:5J!77!!!!!J5?Y5PPJ?Y5PPPY?!!!!!!!!!!!
!!!!!!J@&#57Y&BYY#BJYGBBPY5##!!!!!!!!~~!~:..................:^!?7!!!!!!!7YYJ555YY555P5YY?!!!!!!!!!!!
!!!!!!!J&&#5?&Y?#&B?!P#B7!Y#&J!!!!!!!!!!!~~~~!^::::^::^^~!!~!!!!!!!!!!!75555YJ7!!JY557!Y57!!!!!!!!!!
!!!!!!!!7G@#B&B?G&&B5P#&7^?B&#!!!!!7777777???PY?77J5Y??JJ?????777!!!!!!5P5J?7?JYYYYP5JJY55?!!!!!!!!!
!!!!!!!!!!Y#&@#B#&@&B55BG5PB&&7!!?YYPPJJJY55J77JPYY5??J5P5YJJ?5B5J?7!!7P5J7?Y555PPPPP5555Y5?!!!!!!!!
!!!!!!!!!!7&##P77B&B?^^75BGB@#!!?J?YGB5PBGY5G5J5BGB#5JYGPY5#G5B#5J7J!!?P5YYY55PP5555PP55YY5?!!!!!!!!
???????????G@#B5?G&&BY7!77?P&5??7YGBG7?P#PJGB5J#PPPPB?JG5J5BBPYPG5Y????P55555PYYP5YY5PP5555?????????
????????????P#&#BP&@@&#BGJY#@G??7JY7J!7YY5YJJJGBP775BGJJ?J5YJ77JPGY???Y55YY55PYY55YY55P?7J??????????
?????????????!5@&#&@&&##BB&&&G?5P5Y5PY7!!7?7!?YYJ~~!5Y7!~7??!~!?5BPJ77Y5Y???7?JYYYY55Y!!!???????????
?????????????!!PBGPP55PGGBGPP7?PPGG5YPP5?JJJ77?YJ??75JJ?7JJJ7????JJ?77?555YY??JYYYY5Y7!!!???????????
 */

contract OddClowns is ERC721, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    using Strings for uint256;

    mapping(uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURIextended;
    uint256 public constant MAX_SUPPLY = 7777;

    // Minting price
    uint256 public constant MINT_PRICE = 0.01777 ether;

    constructor() ERC721("OddClowns", "ODC") {}

    function setBaseURI(string memory baseURI_) external onlyOwner {
        _baseURIextended = baseURI_;
    }

    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _baseURIextended;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    function withdraw() external onlyOwner {
      (bool success, ) = msg.sender.call{value: address(this).balance}("");
      require(success, "Transfer Failed");
    }


    function mintNFT(address recipient)
        public
        payable // Require payment
        returns (uint256)
    {
        require(_tokenIds.current() < MAX_SUPPLY, "No more tokens in stock");
        require(msg.value >= MINT_PRICE, "Insufficient payment");
        
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, string(abi.encodePacked( Strings.toString(newItemId),".json")));
        
        return newItemId;
    }
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"mintNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]