contract AlphaPass is ERC1155Supply, Ownable, Pausable {
    string public name;
    string public symbol;

    uint256 public constant TOKEN_ID = 1;
    uint256 public MAX_SUPPLY = 100;
    uint256 public SALE_PRICE = 1.2 ether;
    bool public SALE_ACTIVE = false;
    address public COLLAB = 0xA42a20cB2fA00aa933DC6bb632a5A2e18a6A589F;

    constructor(
        string memory _uri,
        string memory _name,
        string memory _symbol
    ) ERC1155(_uri) {
        name = _name;
        symbol = _symbol;
        _mint(COLLAB, TOKEN_ID, 1, "");
    }

    function setURI(string memory _tokenURI) public onlyOwner {
        _setURI(_tokenURI);
    }

    function setSaleState(bool _state) public onlyOwner {
        require(SALE_ACTIVE != _state, "incorrect state");
        SALE_ACTIVE = _state;
    }

    function setPrice(uint256 _price) external onlyOwner {
        SALE_PRICE = _price;
    }

    function setSupply(uint256 _supply) external onlyOwner {
        MAX_SUPPLY = _supply;
    }

    function setCollab(address _collab) external onlyOwner {
        COLLAB = _collab;
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    /**
     * @notice Allow minting of tokens by anyone while the sale is active
     */
    function mintAlphaPass() external payable {
        require(SALE_ACTIVE, "sale not active");
        require(totalSupply(TOKEN_ID) + 1 <= MAX_SUPPLY, "excceed max supply");
        require(SALE_PRICE <= msg.value, "insufficient eth");

        _mint(msg.sender, TOKEN_ID, 1, "");

        if (totalSupply(TOKEN_ID) >= MAX_SUPPLY) {
            SALE_ACTIVE = false;
        }
    }

    /**
     * @notice Allow owner to send `mintNumber` tokens without cost to multiple addresses
     */
    function gift(address[] calldata _receivers, uint256 _numberOfTokens)
        external
        onlyOwner
    {
        require(
            (totalSupply(TOKEN_ID) + (_receivers.length * _numberOfTokens)) <=
                MAX_SUPPLY,
            "exceed max supply"
        );
        for (uint256 i = 0; i < _receivers.length; i++) {
            _mint(_receivers[i], TOKEN_ID, _numberOfTokens, "");
        }
    }

    /**
     * @notice Override ERC1155 such that zero amount token transfers are disallowed to prevent arbitrary creation of new tokens in the collection.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public override {
        require(amount > 0, "invalid amount");
        return super.safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @notice When the contract is paused, all token transfers are prevented in case of emergency.
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal override whenNotPaused {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
    }

    function withdrawAll() public onlyOwner {
        uint256 balance = address(this).balance;
        if (COLLAB == msg.sender) {
            _withdraw(msg.sender, address(this).balance);
        } else {
            _withdraw(COLLAB, (balance * 9000) / 10000); // 90%
            _withdraw(msg.sender, (balance * 1000) / 10000); // 10%
        }
    }

    function _withdraw(address _addr, uint256 _amt) private {
        (bool success, ) = _addr.call{value: _amt}("");
        require(success, "transfer failed");
    }
}
function gift(address[] calldata _receivers, uint256 _numberOfTokens)
    external
    onlyOwner
{
    require(
        (totalSupply(TOKEN_ID) + (_receivers.length * _numberOfTokens)) <=
            MAX_SUPPLY,
        "exceed max supply"
    );
    for (uint256 i = 0; i < _receivers.length; i++) {
        _mint(_receivers[i], TOKEN_ID, _numberOfTokens, "");
    }
}

/**
 * @notice Allow owner to send `mintNumber` tokens without cost to multiple addresses
 */