# Code generated by moonworm : https://github.com/bugout-dev/moonworm
# Moonworm version : 0.2.4
import json
import os
from typing import Any, Dict, Union

from eth_typing.evm import Address, ChecksumAddress
from web3 import Web3
from web3.contract import ContractFunction

from .web3_util import *

abi_path = os.path.join(os.path.dirname(__file__), "Dropper_abi.json")
with open(abi_path, "r") as abi_file:
    CONTRACT_ABI = json.load(abi_file)


class Contract:
    def __init__(self, web3: Web3, contract_address: ChecksumAddress):
        self.web3 = web3
        self.address = contract_address
        self.contract = web3.eth.contract(address=self.address, abi=CONTRACT_ABI)

    @staticmethod
    def constructor() -> ContractConstructor:
        return ContractConstructor()

    def ERC1155_TYPE(self) -> ContractFunction:
        return self.contract.functions.ERC1155_TYPE()

    def ERC20_TYPE(self) -> ContractFunction:
        return self.contract.functions.ERC20_TYPE()

    def ERC721_TYPE(self) -> ContractFunction:
        return self.contract.functions.ERC721_TYPE()

    def TERMINUS_MINTABLE_TYPE(self) -> ContractFunction:
        return self.contract.functions.TERMINUS_MINTABLE_TYPE()

    def claim(
        self, claimId: int, blockDeadline: int, amount: int, signature: bytes
    ) -> ContractFunction:
        return self.contract.functions.claim(claimId, blockDeadline, amount, signature)

    def claimMessageHash(
        self, claimId: int, claimant: ChecksumAddress, blockDeadline: int, amount: int
    ) -> ContractFunction:
        return self.contract.functions.claimMessageHash(
            claimId, claimant, blockDeadline, amount
        )

    def claimStatus(self, claimId: int) -> ContractFunction:
        return self.contract.functions.claimStatus(claimId)

    def claimUri(self, claimId: int) -> ContractFunction:
        return self.contract.functions.claimUri(claimId)

    def createClaim(
        self, tokenType: int, tokenAddress: ChecksumAddress, tokenId: int, amount: int
    ) -> ContractFunction:
        return self.contract.functions.createClaim(
            tokenType, tokenAddress, tokenId, amount
        )

    def getClaim(self, claimId: int) -> ContractFunction:
        return self.contract.functions.getClaim(claimId)

    def getClaimStatus(
        self, claimId: int, claimant: ChecksumAddress
    ) -> ContractFunction:
        return self.contract.functions.getClaimStatus(claimId, claimant)

    def getSignerForClaim(self, claimId: int) -> ContractFunction:
        return self.contract.functions.getSignerForClaim(claimId)

    def numClaims(self) -> ContractFunction:
        return self.contract.functions.numClaims()

    def onERC1155BatchReceived(
        self,
        arg1: ChecksumAddress,
        arg2: ChecksumAddress,
        arg3: List,
        arg4: List,
        arg5: bytes,
    ) -> ContractFunction:
        return self.contract.functions.onERC1155BatchReceived(
            arg1, arg2, arg3, arg4, arg5
        )

    def onERC1155Received(
        self,
        arg1: ChecksumAddress,
        arg2: ChecksumAddress,
        arg3: int,
        arg4: int,
        arg5: bytes,
    ) -> ContractFunction:
        return self.contract.functions.onERC1155Received(arg1, arg2, arg3, arg4, arg5)

    def onERC721Received(
        self,
        operator: ChecksumAddress,
        from_: ChecksumAddress,
        tokenId: int,
        data: bytes,
    ) -> ContractFunction:
        return self.contract.functions.onERC721Received(operator, from_, tokenId, data)

    def owner(self) -> ContractFunction:
        return self.contract.functions.owner()

    def paused(self) -> ContractFunction:
        return self.contract.functions.paused()

    def renounceOwnership(self) -> ContractFunction:
        return self.contract.functions.renounceOwnership()

    def setClaimStatus(self, claimId: int, status: bool) -> ContractFunction:
        return self.contract.functions.setClaimStatus(claimId, status)

    def setClaimUri(self, claimId: int, uri: str) -> ContractFunction:
        return self.contract.functions.setClaimUri(claimId, uri)

    def setSignerForClaim(
        self, claimId: int, signer: ChecksumAddress
    ) -> ContractFunction:
        return self.contract.functions.setSignerForClaim(claimId, signer)

    def supportsInterface(self, interfaceId: bytes) -> ContractFunction:
        return self.contract.functions.supportsInterface(interfaceId)

    def surrenderPoolControl(
        self,
        poolId: int,
        terminusAddress: ChecksumAddress,
        newPoolController: ChecksumAddress,
    ) -> ContractFunction:
        return self.contract.functions.surrenderPoolControl(
            poolId, terminusAddress, newPoolController
        )

    def transferOwnership(self, newOwner: ChecksumAddress) -> ContractFunction:
        return self.contract.functions.transferOwnership(newOwner)

    def withdrawERC1155(
        self, tokenAddress: ChecksumAddress, tokenId: int, amount: int
    ) -> ContractFunction:
        return self.contract.functions.withdrawERC1155(tokenAddress, tokenId, amount)

    def withdrawERC20(
        self, tokenAddress: ChecksumAddress, amount: int
    ) -> ContractFunction:
        return self.contract.functions.withdrawERC20(tokenAddress, amount)

    def withdrawERC721(
        self, tokenAddress: ChecksumAddress, tokenId: int
    ) -> ContractFunction:
        return self.contract.functions.withdrawERC721(tokenAddress, tokenId)


def deploy(
    web3: Web3,
    contract_constructor: ContractFunction,
    contract_bytecode: str,
    deployer_address: ChecksumAddress,
    deployer_private_key: str,
) -> Contract:
    tx_hash, contract_address = deploy_contract_from_constructor_function(
        web3,
        constructor=contract_constructor,
        contract_bytecode=contract_bytecode,
        contract_abi=CONTRACT_ABI,
        deployer=deployer_address,
        deployer_private_key=deployer_private_key,
    )
    return Contract(web3, contract_address)
