import contracts from "./contracts"
import distributor from "../artifacts/contracts/MerkleDistributor.sol/MerkleDistributor.json"
import zksyncDistributor from "../zksync/artifacts-zk/contracts/MerkleDistributor.sol/ZksyncMerkleDistributor.json"
import {initContractByAbi} from "./utils"

const MERKLE_DISTIBUTOR_CONTRACT = 'merkle_distributor'

const abi = () => {
  return distributor.abi
}

const bytecode = () => {
  return distributor.bytecode
}

const zksyncBytecode = () => {
  return zksyncDistributor.bytecode
}

const deployedAddress = (network : string | number) => {
  if (!contracts[`${network}`]) return null
  return contracts[`${network}`][MERKLE_DISTIBUTOR_CONTRACT]
}

const initContract = (contractKey : string, readOnly = true, web3Provider = null) => {
  return initContractByAbi(distributor.abi, contractKey, readOnly, web3Provider)
}

const owner = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.owner())
}

const token = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.token())
}

const tokenId = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.tokenId())
}

const claimInterface = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.claimInterface())
}

const ipfsCid = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.ipfsCid())
}

const currentRound = (web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.currentRound())
}

const adminSetNewRound = (newRound : number, newMerkleRoot : string, ipfsCid : string, web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, false, web3Provider)
    .then(contract => contract.adminSetNewRound(newRound, newMerkleRoot, ipfsCid))
}

const isClaimed = (index : number, web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, true, web3Provider)
    .then(contract => contract.isClaimed(index))
}

const claim = (index : number, account : string, amount : number, merkleProof : string, web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, false, web3Provider)
    .then(contract => contract.claim(index, account, amount, merkleProof))
}

const adminWithdrawUnclaimed = (beneficiary : string, web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, false, web3Provider)
    .then(contract => contract.adminWithdrawUnclaimed(beneficiary))
}

const transferOwnership = (newOwner : string, web3Provider = null, contractKey = MERKLE_DISTIBUTOR_CONTRACT) => {
  return initContract(contractKey, false, web3Provider)
    .then(contract => contract.transferOwnership(newOwner))
}

export {
  abi,
  bytecode,
  zksyncBytecode,
  deployedAddress,
  owner,
  token,
  tokenId,
  claimInterface,
  ipfsCid,
  currentRound,
  adminSetNewRound,
  isClaimed,
  claim,
  adminWithdrawUnclaimed,
  transferOwnership
}
export default {
  abi,
  bytecode,
  zksyncBytecode,
  deployedAddress,
  owner,
  token,
  tokenId,
  claimInterface,
  ipfsCid,
  currentRound,
  adminSetNewRound,
  isClaimed,
  claim,
  adminWithdrawUnclaimed,
  transferOwnership
}