var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { ethers } from "ethers";
import { getProvider } from "./utils";
import { CONFIG } from "../../config/constants";
// ABI
import ringABI from "../../config/abi/common/abi-ring.json";
import ktonABI from "../../config/abi/common/abi-kton.json";
import apostleAuctionABI from "../../config/abi/common/abi-apostleAuction.json";
import apostleAuctionV3ABI from "../../config/abi/common/abi-apostleAuctionV3.json";
import apostleSiringV3ABI from "../../config/abi/common/abi-apostleSiringV3.json";
import tokenUseV2ABI from "../../config/abi/common/abi-tokenUseV2.json";
import apostleBaseV3ABI from "../../config/abi/common/abi-apostleBaseV3.json";
import apostleBaseV5ABI from "../../config/abi/common/abi-apostleBaseV5.json";
import goldRushRaffleABI from "../../config/abi/common/abi-goldRushRaffle.json";
import clockAuctionV3ABI from "../../config/abi/common/abi-clockAuctionV3.json";
import landResourceABI from "../../config/abi/common/abi-landResource.json";
import landResourceV2ABI from "../../config/abi/common/abi-landResourceV2.json";
import pveTeamABI from "../../config/abi/common/abi-pveTeam.json";
import objectOwnershipABI from "../../config/abi/common/abi-objectOwnership.json";
import settingsRegistry from "../../config/abi/common/abi-settingsRegistry.json";
import lotteryABI from "../../config/abi/common/abi-lottery.json";
import userPointsABI from "../../config/abi/common/abi-userPoints.json";
import furnaceTreasureABI from "../../config/abi/common/abi-furnaceTreasure.json";
import furnaceItemBaseABI from "../../config/abi/common/abi-furnaceItemBase.json";
import furnaceTakebackABI from "../../config/abi/common/abi-furnaceTakeback.json";
import uniswapExchangeABI from "../../config/abi/common/abi-uniswapExchange.json";
import liquidityStakerABI from "../../config/abi/common/abi-liquidityStaker.json";
import liquidityStakerFactoryABI from "../../config/abi/common/abi-liquidityStakerFactory.json";
import materialABI from "../../config/abi/common/abi-material.json";
import elementRaffleABI from "../../config/abi/common/abi-elementRaffle.json";
import pveCraftABI from "../../config/abi/common/abi-pveCraft.json";
export const getContractAddressAndAbiByContractName = (landId, signerOrProvider, contractName, widthABI = true) => {
    var _a;
    const contractAddrAndAbi = {};
    const provider = getProvider(signerOrProvider);
    if (!provider) {
        console.error(`failed to get contract address and abi by contract name. provider undefined, contarct name is ${contractName}`);
        return contractAddrAndAbi;
    }
    const addresses = (_a = CONFIG[landId]) === null || _a === void 0 ? void 0 : _a.address;
    if (addresses) {
        switch (contractName) {
            case "ring":
                contractAddrAndAbi.address = addresses.TOKEN_RING;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "kton":
                contractAddrAndAbi.address = addresses.TOKEN_KTON;
                contractAddrAndAbi.interface = ktonABI;
                break;
            case "gold":
                contractAddrAndAbi.address = addresses.ELEMENT_GOLD;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "wood":
                contractAddrAndAbi.address = addresses.ELEMENT_WOOD;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "water":
                contractAddrAndAbi.address = addresses.ELEMENT_WATER;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "fire":
                contractAddrAndAbi.address = addresses.ELEMENT_FIRE;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "soil":
                contractAddrAndAbi.address = addresses.ELEMENT_SOIL;
                contractAddrAndAbi.interface = ringABI;
                break;
            case "apostleAuction":
                contractAddrAndAbi.address = addresses.APOSTLE_CLOCK_AUCTION;
                contractAddrAndAbi.interface = apostleAuctionABI;
                break;
            case "apostleClockAuctionV3":
                contractAddrAndAbi.address = addresses.APOSTLE_CLOCK_AUCTION;
                contractAddrAndAbi.interface = apostleAuctionV3ABI;
                break;
            case "apostleSiringAuctionV3":
                contractAddrAndAbi.address = addresses.SIRING_CLOCK_AUCTION;
                contractAddrAndAbi.interface = apostleSiringV3ABI;
                break;
            case "apostleTokenUseV2":
                contractAddrAndAbi.address = addresses.TOKEN_USE;
                contractAddrAndAbi.interface = tokenUseV2ABI;
                break;
            case "apostleBaseV3":
                contractAddrAndAbi.address = addresses.APOSTLE_BASE;
                contractAddrAndAbi.interface = apostleBaseV3ABI;
                break;
            case "apostleBaseV5":
                contractAddrAndAbi.address = addresses.APOSTLE_BASE;
                contractAddrAndAbi.interface = apostleBaseV5ABI;
                break;
            case "goldRushRaffle":
                contractAddrAndAbi.address = addresses.GOLD_RUSH_RAFFLE;
                contractAddrAndAbi.interface = goldRushRaffleABI;
                break;
            case "landClockAuctionV3":
                contractAddrAndAbi.address = addresses.LAND_CLOCK_AUCTION;
                contractAddrAndAbi.interface = clockAuctionV3ABI;
                break;
            case "apostleLandResource":
                contractAddrAndAbi.address = addresses.LAND_RESOURCE;
                contractAddrAndAbi.interface = landResourceABI;
                break;
            case "apostleLandResourceV2":
                contractAddrAndAbi.address = addresses.LAND_RESOURCE;
                contractAddrAndAbi.interface = landResourceV2ABI;
                break;
            case "pveTeam":
                contractAddrAndAbi.address = addresses.PVETEAM_PROXY;
                contractAddrAndAbi.interface = pveTeamABI;
                break;
            case "pveCraft":
                contractAddrAndAbi.address = addresses.CRAFTBASE_PROXY;
                contractAddrAndAbi.interface = pveCraftABI;
                break;
            case "objectOwnership":
                contractAddrAndAbi.address = addresses.OBJECTOWNERSHIP;
                contractAddrAndAbi.interface = objectOwnershipABI;
                break;
            case "settingsRegistry":
                contractAddrAndAbi.address = addresses.SETTINGSREGISTRY;
                contractAddrAndAbi.interface = settingsRegistry;
                break;
            case "lottery":
                contractAddrAndAbi.address = addresses.POINTS_REWARD_POOL;
                contractAddrAndAbi.interface = lotteryABI;
                break;
            case "userPoints":
                contractAddrAndAbi.address = addresses.TOKEN_USER_POINTS;
                contractAddrAndAbi.interface = userPointsABI;
                break;
            case "furnaceTreasure":
                contractAddrAndAbi.address = addresses.FURNACE_TREASURE;
                contractAddrAndAbi.interface = furnaceTreasureABI;
                break;
            case "furnaceItemBase":
                contractAddrAndAbi.address = addresses.FURNACE_ITEM_BASE;
                contractAddrAndAbi.interface = furnaceItemBaseABI;
                break;
            case "furnaceTakeback":
                contractAddrAndAbi.address = addresses.FURNACE_TAKEBACK;
                contractAddrAndAbi.interface = furnaceTakebackABI;
                break;
            case "uniswapExchange":
                contractAddrAndAbi.address = addresses.UNISWAP_EXCHANGE;
                contractAddrAndAbi.interface = uniswapExchangeABI;
                break;
            case "liquidityStaker":
                contractAddrAndAbi.address = "";
                contractAddrAndAbi.interface = liquidityStakerABI;
                break;
            case "liquidityStakerFactory":
                contractAddrAndAbi.address = addresses.STAKINGREWARDSFACTORY;
                contractAddrAndAbi.interface = liquidityStakerFactoryABI;
                break;
            case "material":
                contractAddrAndAbi.address = addresses.MATERIAL_PROXY;
                contractAddrAndAbi.interface = materialABI;
                break;
            case "goldElementRaffle":
                contractAddrAndAbi.address = addresses.GOLDRAFFLEPOOL_PROXY;
                contractAddrAndAbi.interface = elementRaffleABI;
                break;
            case "woodElementRaffle":
                contractAddrAndAbi.address = addresses.WOODRAFFLEPOOL_PROXY;
                contractAddrAndAbi.interface = elementRaffleABI;
                break;
            case "waterElementRaffle":
                contractAddrAndAbi.address = addresses.WATERRAFFLEPOOL_PROXY;
                contractAddrAndAbi.interface = elementRaffleABI;
                break;
            case "fireElementRaffle":
                contractAddrAndAbi.address = addresses.FIRERAFFLEPOOL_PROXY;
                contractAddrAndAbi.interface = elementRaffleABI;
                break;
            case "soilElementRaffle":
                contractAddrAndAbi.address = addresses.SOILRAFFLEPOOL_PROXY;
                contractAddrAndAbi.interface = elementRaffleABI;
                break;
        }
    }
    !contractAddrAndAbi.address &&
        console.warn(`failed to get contract address by contract name. contarct name is ${contractName}`);
    !contractAddrAndAbi.interface &&
        console.warn(`failed to get contract interface by contract name. contarct name is ${contractName}`);
    return contractAddrAndAbi;
};
export const getContract = (signerOrProvider, contractAddress, contractInterface) => {
    // try {
    const contract = new ethers.Contract(contractAddress, contractInterface, signerOrProvider);
    return contract;
    // } catch (err) {
    //   console.error("failed to get contract. error:", err);
    // }
};
export const getContractByContractName = (landId, signerOrProvider, contractName) => {
    const contractAddrAndAbi = getContractAddressAndAbiByContractName(landId, signerOrProvider, contractName);
    const contract = new ethers.Contract(contractAddrAndAbi.address, contractAddrAndAbi.interface, signerOrProvider);
    return contract;
    // if (contractAddrAndAbi.address && contractAddrAndAbi.interface) {
    //   try {
    //     const contract = new ethers.Contract(contractAddrAndAbi.address, contractAddrAndAbi.interface, signerOrProvider);
    //     return contract;
    //   } catch (err) {
    //     console.error(`failed to get contract by contract name. contarct name is ${contractName}, error:`, err);
    //   }
    // } else {
    //   console.error(
    //     `failed to get contract by contract name. address or abi undefined, contarct name is ${contractName}`
    //   );
    // }
};
const defaultCallback = {
    errorCallback: ({ error }) => {
        void error;
    },
    // responseCallback: ({ transactionHash }) => { console.info(transactionHash) },
    // successCallback: ({ transactionHash }) => { console.info(transactionHash) },
};
export const triggerContract = (contract, methodName, contractArgs = [], callback = defaultCallback, overrides) => __awaiter(void 0, void 0, void 0, function* () {
    const { errorCallback, responseCallback, successCallback } = callback;
    // try {
    const response = yield contract[methodName](...contractArgs, Object.assign({}, overrides));
    responseCallback && responseCallback({ transactionHash: response.hash });
    // const receipt: ethers.providers.TransactionReceipt = await response.wait(2);
    // if (receipt.byzantium && receipt.status === 1) {
    //   successCallback && successCallback({ transactionHash: receipt.transactionHash });
    // }
    return response;
    // } catch (err) {
    //   console.error(err);
    //   errorCallback({ error: err });
    // }
});
export const triggerContractByContractName = (landId, signerOrProvider, contractName, methodName, contractArgs = [], callback = defaultCallback, overrides) => __awaiter(void 0, void 0, void 0, function* () {
    const contract = yield getContractByContractName(landId, signerOrProvider, contractName);
    return yield triggerContract(contract, methodName, contractArgs, callback, overrides);
    // if (contract) {
    //   return await triggerContract(contract, methodName, contractArgs, callback, overrides);
    // } else {
    //   callback &&
    //     callback.errorCallback({
    //       error: new Error(
    //         `failed to trigger contract by contract name. contract undefined, contract name is ${contractName}`
    //       ),
    //     });
    // }
});
export const viewContract = (contract, methodName, contractArgs = [], callback = defaultCallback) => __awaiter(void 0, void 0, void 0, function* () {
    const { errorCallback } = callback;
    try {
        return yield contract.functions[methodName](...contractArgs);
    }
    catch (err) {
        console.error(err);
        errorCallback({ error: err });
    }
    return [];
});
export const viewContractByContractName = (landId, signerOrProvider, contractName, methodName, contractArgs = [], callback = defaultCallback) => __awaiter(void 0, void 0, void 0, function* () {
    const contract = yield getContractByContractName(landId, signerOrProvider, contractName);
    if (contract) {
        return yield viewContract(contract, methodName, contractArgs, callback);
    }
    else {
        callback &&
            callback.errorCallback({
                error: new Error(`failed to view contract by contract name. contract undefined, contract name is ${contractName}`),
            });
        return [];
    }
});
