import { Interface } from "@ethersproject/abi";
import { formatBytes32String } from "@ethersproject/strings";
import { abis, utils, SellerUpdateFields, DisputeResolverUpdateFields } from "./types";
import { AddressZero } from "@ethersproject/constants";
import { INITIAL_COLLECTION_ID } from "./handler";
export const bosonAccountHandlerIface = new Interface(abis.IBosonAccountHandlerABI);
export function encodeCreateSeller(seller, collectionSalt) {
    const sellerArgs = createSellerArgsToStruct(seller, collectionSalt);
    return bosonAccountHandlerIface.encodeFunctionData("createSeller", [
        sellerArgs.sellerStruct,
        sellerArgs.authTokenStruct,
        sellerArgs.voucherInitValues
    ]);
}
export function encodeCreateNewCollection(collection) {
    const collectionArgs = createCollectionArgsToStruct(collection);
    return bosonAccountHandlerIface.encodeFunctionData("createNewCollection", [
        collectionArgs.externalId,
        collectionArgs.voucherInitValues
    ]);
}
export function encodeUpdateSeller(seller) {
    const sellerArgs = updateSellerArgsToStruct(seller);
    return bosonAccountHandlerIface.encodeFunctionData("updateSeller", [
        sellerArgs.sellerStruct,
        sellerArgs.authTokenStruct
    ]);
}
export function encodeOptInToSellerUpdate(seller) {
    const fieldsToUpdate = [];
    Object.entries(SellerUpdateFields).forEach(([key, value]) => {
        if (seller.fieldsToUpdate[key]) {
            fieldsToUpdate.push(value);
        }
    });
    return bosonAccountHandlerIface.encodeFunctionData("optInToSellerUpdate", [
        seller.id,
        fieldsToUpdate
    ]);
}
export function encodeCreateBuyer(buyer) {
    const buyerStruct = argsToBuyerStruct(buyer);
    return bosonAccountHandlerIface.encodeFunctionData("createBuyer", [
        buyerStruct
    ]);
}
export function encodeCreateDisputeResolver(args) {
    return bosonAccountHandlerIface.encodeFunctionData("createDisputeResolver", [
        createDisputeResolverArgsToDisputeResolverStruct(args),
        args.fees,
        args.sellerAllowList || []
    ]);
}
export function encodeAddFeesToDisputeResolver(args) {
    return bosonAccountHandlerIface.encodeFunctionData("addFeesToDisputeResolver", [args.disputeResolverId, args.fees]);
}
export function encodeAddSellersToAllowList(args) {
    return bosonAccountHandlerIface.encodeFunctionData("addSellersToAllowList", [
        args.disputeResolverId,
        args.sellerAllowList
    ]);
}
export function encodeRemoveFeesFromDisputeResolver(args) {
    return bosonAccountHandlerIface.encodeFunctionData("removeFeesFromDisputeResolver", [args.disputeResolverId, args.feeTokenAddresses]);
}
export function encodeRemoveSellersFromAllowList(args) {
    return bosonAccountHandlerIface.encodeFunctionData("removeSellersFromAllowList", [args.disputeResolverId, args.sellerAllowList]);
}
export function encodeUpdateDisputeResolver(disputeResolver) {
    return bosonAccountHandlerIface.encodeFunctionData("updateDisputeResolver", [
        disputeResolver
    ]);
}
export function encodeOptInToDisputeResolverUpdate(disputeResolver) {
    const fieldsToUpdate = [];
    Object.entries(DisputeResolverUpdateFields).forEach(([key, value]) => {
        if (disputeResolver.fieldsToUpdate[key]) {
            fieldsToUpdate.push(value);
        }
    });
    return bosonAccountHandlerIface.encodeFunctionData("optInToDisputeResolverUpdate", [disputeResolver.id, fieldsToUpdate]);
}
// TODO: add a unit test for collectionId
export function createSellerArgsToStruct(args, collectionSalt) {
    const { authTokenId, authTokenType, contractUri, royaltyPercentage, ...sellerStructArgs } = args;
    return {
        sellerStruct: argsToSellerStruct(sellerStructArgs),
        authTokenStruct: {
            tokenId: authTokenId,
            tokenType: authTokenType
        },
        voucherInitValues: {
            contractURI: contractUri,
            royaltyPercentage,
            collectionSalt
        }
    };
}
export function createCollectionArgsToStruct(args) {
    const { collectionId, contractUri } = args;
    const collectionSalt = args.collectionSalt ||
        formatBytes32String(collectionId || INITIAL_COLLECTION_ID);
    return {
        externalId: collectionId,
        voucherInitValues: {
            contractURI: contractUri,
            royaltyPercentage: "0", // useless after protocol v2.4.0
            collectionSalt
        }
    };
}
export function updateSellerArgsToStruct(args) {
    const { authTokenId, authTokenType, ...sellerStructArgs } = args;
    return {
        sellerStruct: argsToSellerStruct(sellerStructArgs),
        authTokenStruct: {
            tokenId: authTokenId,
            tokenType: authTokenType
        }
    };
}
function argsToSellerStruct(args) {
    return {
        // NOTE: It doesn't matter which values we set for `id` and `active` here
        // as they will be overridden by the contract. But to conform to the struct
        // we need to set some arbitrary values.
        id: "0",
        active: true,
        clerk: AddressZero,
        ...args
    };
}
function argsToBuyerStruct(args) {
    return {
        // NOTE: It doesn't matter which values we set for `id` and `active` here
        // as they will be overridden by the contract. But to conform to the struct
        // we need to set some arbitrary values.
        id: "0",
        active: true,
        ...args
    };
}
function createDisputeResolverArgsToDisputeResolverStruct(args) {
    return {
        // NOTE: It doesn't matter which values we set for `id` and `active` here
        // as they will be overridden by the contract. But to conform to the struct
        // we need to set some arbitrary values.
        id: "0",
        active: true,
        clerk: AddressZero,
        ...args,
        escalationResponsePeriod: utils.timestamp.msToSec(args.escalationResponsePeriodInMS)
    };
}
export function encodeIsSellerSaltAvailable(adminAddress, salt) {
    return bosonAccountHandlerIface.encodeFunctionData("isSellerSaltAvailable", [
        adminAddress,
        salt
    ]);
}
export function decodeIsSellerSaltAvailable(result) {
    const [isAvailable] = bosonAccountHandlerIface.decodeFunctionResult("isSellerSaltAvailable", result);
    return isAvailable;
}
export function encodeCalculateCollectionAddress(sellerId, collectionSalt) {
    return bosonAccountHandlerIface.encodeFunctionData("calculateCollectionAddress", [sellerId, collectionSalt]);
}
export function decodeCalculateCollectionAddress(result) {
    const [collectionAddress, isAvailable] = bosonAccountHandlerIface.decodeFunctionResult("calculateCollectionAddress", result);
    return { collectionAddress, isAvailable };
}
export function encodeAddRoyaltyRecipients(args) {
    return bosonAccountHandlerIface.encodeFunctionData("addRoyaltyRecipients", [
        args.sellerId,
        args.royaltyRecipients
    ]);
}
export function encodeUpdateRoyaltyRecipients(args) {
    return bosonAccountHandlerIface.encodeFunctionData("updateRoyaltyRecipients", [args.sellerId, args.royaltyRecipientIds, args.royaltyRecipients]);
}
export function encodeRemoveRoyaltyRecipients(args) {
    return bosonAccountHandlerIface.encodeFunctionData("removeRoyaltyRecipients", [args.sellerId, args.royaltyRecipientIds]);
}
export function encodeGetRoyaltyRecipients(args) {
    return bosonAccountHandlerIface.encodeFunctionData("getRoyaltyRecipients", [
        args.sellerId
    ]);
}
export function decodeGetRoyaltyRecipients(result) {
    const [royaltyRecipients] = bosonAccountHandlerIface.decodeFunctionResult("getRoyaltyRecipients", result);
    return royaltyRecipients;
}
//# sourceMappingURL=interface.js.map