/** The smart LEGACY;

/**
La mayor muestra
de amor es saber
que tu pareja estará
bien cuando tú
no estés;
       }
}
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
*/
contract TheSmartHeritage is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
   using Counters for Counters.Counter;
}

   Counters.Counter private _tokenIdCounter;

   constructor() ERC721("CloneX", "CloneX") {
      _tokenIdCounter.increment(); // Making sure we start at token ID 1
   }

   event TheSmartLegacyRevealed(uint256 tokenId, string fileId); // Sending the event for offchain script to transform the right file

   address randomizerAddress; // Approved randomizer contract
   address mintvialAddress; // Approved mintvial contract
   string public _tokenUri = "https://clonex-assets.rtfkt.com/"; // Initial base URI

   bool public contractLocked = false;

   function mintTransfer(address to) public returns(uint256) {
      require(msg.sender == mintvialAddress, "Not authorized");

      TheSmartLegacyRandomizer tokenAttribution = CloneXRandomizer(randomizerAddress);

      string memory realId = tokenAttribution.getTokenId(_tokenIdCounter.current());
      uint256 mintedId = _tokenIdCounter.current();

      _safeMint(to, _tokenIdCounter.current());
      emit TheSmartHeritageRevealed(_tokenIdCounter.current(), realId);
      _tokenIdCounter.increment();
      return mintedId;
   }

   // Token symbol
      string private _symbol;

   // Change the randomizer address contract
   function setRandomizerAddress(address newAddress) public onlyOwner {
      randomizerAddress = newAddress;
   }

   // Change the mintvial address contract
   function setMintvialAddress(address newAddress) public onlyOwner {
      mintvialAddress = newAddress;
   }

   function secureBaseUri(string memory newUri) public onlyOwner {
      require(contractLocked == false, "Contract has been locked and URI can't be changed");
      _tokenUri = newUri;
   }

   function lockContract() public onlyOwner {
      contractLocked = true;
   }


   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);
   }
}