contract Zapper_NFT_Bridge_V1 is ERC1155Receiver, Ownable {
    IZapper_NFT public Zapper_NFT_V1;

    IZapper_NFT public Zapper_NFT_V2;

    // Season 1 NFT burn address
    address public constant BURN_ADDRESS =
        0x000000000000000000000000000000000000dEaD;

    // Maps the V1 NFT ID to the V2 NFT ID
    mapping(uint256 => uint256) public mintIDs;

    bool public paused;

    modifier pausable {
        require(!paused);
        _;
    }

    constructor(address V1_Address, address V2_Address) {
        Zapper_NFT_V1 = IZapper_NFT(V1_Address);
        Zapper_NFT_V2 = IZapper_NFT(V2_Address);
    }

    /**
     * @notice Bridges and crafts V2 Zapper NFTs from V1 NFTs
     * @dev This is irreversible as tokens are sent to the
     * burn address
     * @param id The ID of the V1 NFT being used in crafting
     * @param quantity The quantity of the V1 NFT being being
     * used in crafting
     */
    function bridgeAndCraft(uint256 id, uint256 quantity) external pausable {
        uint256 mintID = mintIDs[id];
        require(mintID != 0, "Invalid ID");

        uint256 craftingRequirement = Zapper_NFT_V2.craftingRequirement();
        require(
            quantity % craftingRequirement == 0,
            "Incorrect quantity for crafting"
        );

        Zapper_NFT_V1.safeTransferFrom(
            msg.sender,
            BURN_ADDRESS,
            id,
            quantity,
            new bytes(0)
        );

        uint256 mintQuantity = quantity / craftingRequirement;

        Zapper_NFT_V2.mint(mintID, mintQuantity);

        Zapper_NFT_V2.safeTransferFrom(
            address(this),
            msg.sender,
            mintID,
            mintQuantity,
            new bytes(0)
        );
    }

    function setMintIDs(uint256[] calldata fromIds, uint256[] calldata toIds)
        external
        onlyOwner
    {
        require(fromIds.length == toIds.length, "Mismatched array lengths");
        for (uint256 i = 0; i < fromIds.length; i++) {
            mintIDs[fromIds[i]] = toIds[i];
        }
    }

    function updateContracts(address V1_Address, address V2_Address)
        external
        onlyOwner
    {
        Zapper_NFT_V1 = IZapper_NFT(V1_Address);
        Zapper_NFT_V2 = IZapper_NFT(V2_Address);
    }

    function pause() external onlyOwner {
        paused = !paused;
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external pure override returns (bytes4) {
        return
            bytes4(
                keccak256(
                    "onERC1155Received(address,address,uint256,uint256,bytes)"
                )
            );
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external pure override returns (bytes4) {
        return
            bytes4(
                keccak256(
                    "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"
                )
            );
    }
}
function bridgeAndCraft(uint256 id, uint256 quantity) external pausable {
    uint256 mintID = mintIDs[id];
    require(mintID != 0, "Invalid ID");

    uint256 craftingRequirement = Zapper_NFT_V2.craftingRequirement();
    require(
        quantity % craftingRequirement == 0,
        "Incorrect quantity for crafting"
    );

    Zapper_NFT_V1.safeTransferFrom(
        msg.sender,
        BURN_ADDRESS,
        id,
        quantity,
        new bytes(0)
    );

    uint256 mintQuantity = quantity / craftingRequirement;

    Zapper_NFT_V2.mint(mintID, mintQuantity);

    Zapper_NFT_V2.safeTransferFrom(
        address(this),
        msg.sender,
        mintID,
        mintQuantity,
        new bytes(0)
    );
}

/**
 * @notice Bridges and crafts V2 Zapper NFTs from V1 NFTs
 * @dev This is irreversible as tokens are sent to the
 * burn address
 * @param id The ID of the V1 NFT being used in crafting
 * @param quantity The quantity of the V1 NFT being being
 * used in crafting
 */