// ====== FOR ALL CRYPTO BUILDERS ======
// 
// コントラクトを読んでくれてありがとうございます！！
// こちらのコントラクトは twitter.com/chillx2land による習作です！
// 会社の方でもNFTの事業やるので自分のNFTを発行することをテーマにコード書いてみました。
// (習作がきっかけですが運営はもちろん本気でやります。)
// 市況についていろんなことを言う人がいますが、It’s best to pay no mind to “Mr. Market”.
// 信じた技術で手を動かしてプロダクトで世の中に価値を提供することに僕は集中します。
// 思想に共感する人はぜひWeb3勉強会(twitter.com/_42Crypto)にDMをください。
// WAGMI!!
// 
// =========== THANK YOU !! ===========

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "hardhat/console.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Mint is ERC721URIStorage, Ownable, ReentrancyGuard {

  using Counters for Counters.Counter;
  Counters.Counter private _tokenIds;

  constructor() ERC721 ("Chill's NFT Genesis", "CHLL"){}

  function mint() public payable callerIsUser{

    uint256 newItemId = _tokenIds.current();
    require(_tokenIds.current() <= 5, "reached max supply");
    _safeMint(msg.sender, newItemId);
    refundIfOver(0.05 ether);

    console.log(newItemId);

    if (newItemId == 1){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Gradient.json");
    } else if (newItemId == 2){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Marble.json");
    } else if (newItemId == 3){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Stone.json");
    } else if (newItemId == 4){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Tile.json");
    } else {
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Wave.json");
    }
    
    console.log("An NFT w/ ID %s has been minted to %s", newItemId, msg.sender);

    _tokenIds.increment();
  }

  modifier callerIsUser() {
    require(tx.origin == msg.sender, "The caller is another contract");
    _;
  }

  function refundIfOver(uint256 price) private {
    require(msg.value >= price, "Need to send more ETH.");
    if (msg.value > price) {
      payable(msg.sender).transfer(msg.value - price);
    }
  }

  function remain() public view returns (uint256) {
    unchecked {
      return 5 - _tokenIds.current();
    }
  }

  function withdraw(address payable _to) public onlyOwner nonReentrant{
    _to.transfer(address(this).balance);
  }

  function gift(address payable _to) public onlyOwner nonReentrant{
    uint256 newItemId = _tokenIds.current();
    require(_tokenIds.current() <= 5, "reached max supply");
    _safeMint(_to, newItemId);

    if (newItemId == 1){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Gradient.json");
    } else if (newItemId == 2){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Marble.json");
    } else if (newItemId == 3){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Stone.json");
    } else if (newItemId == 4){
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Tile.json");
    } else {
      _setTokenURI(newItemId, "ipfs://QmexVcFyjZNzvTmY597xfHP22bHUNH86GfX8QHJJAXh75J/Wave.json");
    }

    console.log("An NFT w/ ID %s has been minted to %s", newItemId, msg.sender);

    _tokenIds.increment();
  }
}
[{"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":[{"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 payable","name":"_to","type":"address"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","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":[],"name":"mint","outputs":[],"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":"remain","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"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":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]