contract Sakinu is ERC721Enumerable, Ownable, ReentrancyGuard {
  using Strings for uint256;
  using Counters for Counters.Counter;

  // ========== data ==========
  bool public pause = false;
  bool public reveal = false;
  uint256 public cost = 0.09 ether;
  uint256 public supply = 10000;
  string public revealed_uri;
  string public not_revealed_uri;
  Counters.Counter private _token_ids;
  
  // ========== constructor ==========
  constructor(
    string memory _init_revealed_uri,
    string memory _init_not_revealed_uri
  ) ERC721("Sakinu", "SAK") {
    set_revealed_uri(_init_revealed_uri);
    set_not_revealed_uri(_init_not_revealed_uri);
  }

  // ========== base uri ==========
  function _baseURI() internal view virtual override returns (string memory) {
    return revealed_uri;
  }

  // ========== purchase ==========
  function Purchase(uint256 _mint_amount) public payable nonReentrant {

    uint256 minted_supply = totalSupply();
    require(_mint_amount > 0, "at least 1");
    require(minted_supply + _mint_amount <= supply, "supply exceeded");

    if (msg.sender != owner()) {
    require(!pause, "contrat is paused");
      require(msg.value >= cost * _mint_amount, "insufficients funds");
    }

    uint256 _new_token_id;
    for (uint256 i = 1; i <= _mint_amount; i++) {
      _token_ids.increment();
      _new_token_id = _token_ids.current();
      _safeMint(msg.sender, _new_token_id);
    }
  }

  // ========== airdrop ==========
  function Airdrop(uint256 _mint_amount, address _to) public payable onlyOwner {
    uint256 _new_token_id;
    for (uint256 i = 1; i <= _mint_amount; i++) {
      _token_ids.increment();
      _new_token_id = _token_ids.current();
      _safeMint(_to, _new_token_id);
    }
  }

  // ========== token return ==========
  function tokenURI(uint256 _token_id) public view virtual override returns (string memory) {
    require(_exists(_token_id));

    if(reveal == false) {
      return not_revealed_uri;
    }

    string memory current_base_uri = _baseURI();
    return bytes(current_base_uri).length > 0 ? string(abi.encodePacked(current_base_uri, _token_id.toString())) : "";
  }

  // ========== func ==========
  function set_revealed_uri(string memory _new_revealed_uri) public onlyOwner {
    revealed_uri = _new_revealed_uri;
  }

  function set_not_revealed_uri(string memory _new_not_revealed_uri) public onlyOwner {
    not_revealed_uri = _new_not_revealed_uri;
  }

  function set_cost(uint256 _new_cost) public onlyOwner {
    cost = _new_cost;
  }

  function set_supply(uint256 _new_supply) public onlyOwner {
    supply = _new_supply;
  }

  function set_pause(bool _new_pause_state) public onlyOwner {
    pause = _new_pause_state;
  }

  function set_reveal(bool _new_reveal_state) public onlyOwner {
    reveal = _new_reveal_state;
  }

  function transfert_nft(address _from, address _to, uint256 _token_id) public onlyOwner {
    safeTransferFrom(_from, _to, _token_id);
  }

  // ========== pay ==========
  function Pay() public payable onlyOwner {
    uint256 _balance = address(this).balance;
    payable(0x15aD2f48b90BAC4bEBa8EA1cE6bf52d8bb6eAB22).transfer(_balance);
  }
}
// @name:    Sakinu
// @symbol:  SAK
// @desc:    10,000 Unique Sakinu Female Characters
// @project: https://www.instagram.com/sakinuchan.nft/
// @url:     https://www.sakinu.io/
function set_revealed_uri(string memory _new_revealed_uri) public onlyOwner {
  revealed_uri = _new_revealed_uri;
}

// ========== func ==========