//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract NarutoMuseumPass is ERC721("Naruto Museum Pass", "NMP"), Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _goldTokenIds;
    Counters.Counter private _silverTokenIds;
    mapping(address => bool) public minter;
    string private baseURL = "ipfs://bafybeidtuggvku6bqd6cu2dqt4tj6sfc6f4qwdcpli5otacyhyghq5xbrq";
    uint256 private _goldTotalSupply;

    constructor(uint256 goldTotalSupply) {
        _goldTotalSupply = goldTotalSupply;
    }

    modifier onlyMinter() {
        require(minter[_msgSender()], "Only minter.");
        _;
    }

    function setMinter(address _minter, bool _isMinter) external onlyOwner {
        minter[_minter] = _isMinter;
    }

    function mintGold(address _receiver) public onlyMinter {
        _goldTokenIds.increment();
        require(_goldTokenIds.current() <= _goldTotalSupply, "Total supply reached.");
        uint256 tokenId = _goldTokenIds.current();
        _safeMint(_receiver, tokenId);
    }

    function batchMintGold(address[] memory _receivers) external onlyMinter {
        for (uint256 i = 0; i < _receivers.length; i++) {
            mintGold(_receivers[i]);
        }
    }

    function mintSilver(address _receiver) public onlyMinter {
        _silverTokenIds.increment();
        uint256 tokenId = _silverTokenIds.current();
        _safeMint(_receiver, _goldTotalSupply + tokenId);
    }

    function batchMintSilver(address[] memory _receivers) external onlyMinter {
        for (uint256 i = 0; i < _receivers.length; i++) {
            mintSilver(_receivers[i]);
        }
    }

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

        string memory trait;
        string memory image;
        string memory animationUrl;
        if (tokenId <= _goldTotalSupply) {
            trait = "Gold";
            image = string(abi.encodePacked(baseURL, "/gold.png"));
            animationUrl = string(abi.encodePacked(baseURL, "/gold.mp4"));
        } else {
            tokenId = tokenId - _goldTotalSupply;
            trait = "Silver";
            image = string(abi.encodePacked(baseURL, "/silver.png"));
            animationUrl = string(abi.encodePacked(baseURL, "/silver.mp4"));
        }

        return
            string(
                abi.encodePacked(
                    '{"name":"Naruto Museum Pass | ',
                    trait,
                    " #",
                    Strings.toString(tokenId),
                    '","description":"This is an official pass of NFT Naruto Museum. The pass provides the right to participate in future projects of the museum, such as Naruto Launchpad, Naruto Meta Museum, etc.","attributes":[{"trait_type":"Edition","value":"',
                    trait,
                    '"}],"image":"',
                    image,
                    '","external_url":"',
                    image,
                    '","animation_url":"',
                    animationUrl,
                    '"}'
                )
            );
    }
}
[{"inputs":[{"internalType":"uint256","name":"goldTotalSupply","type":"uint256"}],"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":[{"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":"address[]","name":"_receivers","type":"address[]"}],"name":"batchMintGold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_receivers","type":"address[]"}],"name":"batchMintSilver","outputs":[],"stateMutability":"nonpayable","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":"_receiver","type":"address"}],"name":"mintGold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"mintSilver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"address","name":"_minter","type":"address"},{"internalType":"bool","name":"_isMinter","type":"bool"}],"name":"setMinter","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"}]