import * as fuels from 'fuels';
import { Contract, StorageSlot, InvokeFunction, BigNumberish, BN, AbstractAddress, Account, Provider, Interface, FunctionFragment } from 'fuels';

declare enum AllowedProviders {
    FuelProvider = "FuelProvider",
    WalletProvider = "WalletProvider"
}
declare enum Networks {
    Testnet = "testnet"
}
declare enum MarketplaceErrorCodes {
    InsufficientBalance = "InsufficientBalance",
    InvalidArgumentsError = "InvalidArgumentsError",
    InvalidNetworkArgument = "InvalidNetworkArgument",
    NetworkRequestError = "NetworkRequestError",
    PropertyUndefinedError = "PropertyUndefinedError",
    ServerError = "ServerError"
}

declare class MarketplaceError<TErrorData = unknown> extends Error {
    code: MarketplaceErrorCodes;
    errorData?: TErrorData | undefined;
    constructor(message: string, code: MarketplaceErrorCodes, errorData?: TErrorData | undefined);
}

interface HooksReturn<TReturnData = unknown> {
    fetching: boolean;
    data: TReturnData;
    error: unknown;
}
interface HooksArgs {
    network: Networks;
    limit?: number;
}
interface AllNftsInCollectionArgs {
    network: Networks;
    nftStandard: 'NFT' | 'SEMI_FT';
    contractAddress: `0x${string}`;
}
interface NftDetailsArgs extends HooksArgs {
    contractAddress: `0x${string}`;
    tokenId: string;
    nftStandard: 'NFT' | 'SEMI_FT';
}

interface MarketplaceListings {
    listingId: number;
    isActive: boolean;
    nftAddress: `0x${string}`;
    tokenStandard: 'NFT' | 'SEMI_FT';
    tokenId: `0x${string}`;
    assetId: `0x${string}`;
    tokenQuantity: number;
    pricePerItem: string;
    sellerAddress: `0x${string}`;
    tokenName: string;
    tokenImage: string;
    tokenAssetMedia: string;
}
interface MarketplaceCollections {
    contractAddress: `0x${string}`;
    tokenStandard: 'NFT' | 'SEMI_FT';
    collectionName: string;
    collectionSymbol: string;
    floorPrice: string;
    totalItemsListed: number;
    bannerImage: string;
}
interface TokensInCollection {
    tokenName: string;
    tokenImage: string;
    tokenAssetMedia: string;
    description: string;
    contractAddress: `0x${string}`;
    tokenId: `0x${string}`;
    assetId: `0x${string}`;
    tokenStandard: 'NFT' | 'SEMI_FT';
    contractName: string;
    contractSymbol: string;
}
interface OmittedMarketplaceListings extends Omit<MarketplaceListings, 'tokenName' | 'tokenImage' | 'tokenAssetMedia'> {
}
interface NftMetadata {
    tokenName: string;
    tokenImage: string;
    tokenAssetMedia: string;
    description: string;
}
interface NftDetails {
    listingData: OmittedMarketplaceListings[];
    nftMetadata: NftMetadata;
}

declare abstract class MarketplaceServices {
    abstract setProperties(...args: Array<unknown>): this;
    abstract execute(): Promise<unknown>;
}

declare const useAllNftsInCollection: ({ network, nftStandard, contractAddress, }: AllNftsInCollectionArgs) => Readonly<HooksReturn<TokensInCollection[]>>;

declare const useCollections: ({ network, limit }: HooksArgs) => Readonly<HooksReturn<MarketplaceCollections[]>>;

declare const useListings: ({ network, limit }: HooksArgs) => Readonly<HooksReturn<MarketplaceListings[]>>;

declare const useNft: ({ network, limit, contractAddress, nftStandard, tokenId, }: NftDetailsArgs) => Readonly<HooksReturn<NftDetails>>;

/* Autogenerated file. Do not edit manually. */

/* eslint-disable max-classes-per-file */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/consistent-type-imports */

/*
  Fuels version: 0.94.5
*/

/**
 * Mimics Sway Enum.
 * Requires one and only one Key-Value pair and raises error if more are provided.
 */
type Enum<T> = {
  [K in keyof T]: Pick<T, K> & { [P in Exclude<keyof T, K>]?: never };
}[keyof T];

/**
 * Mimics Sway Option and Vectors.
 * Vectors are treated like arrays in Typescript.
 */
type Option<T> = T | undefined;

type Vec<T> = T[];

type IdentityInput = Enum<{
    Address: AddressInput;
    ContractId: ContractIdInput;
}>;
type IdentityOutput = Enum<{
    Address: AddressOutput;
    ContractId: ContractIdOutput;
}>;
declare enum NFTStandardInput {
    NFT = "NFT",
    SEMI_FT = "SEMI_FT"
}
declare enum NFTStandardOutput {
    NFT = "NFT",
    SEMI_FT = "SEMI_FT"
}
type StateOutput = Enum<{
    Uninitialized: void;
    Initialized: IdentityOutput;
    Revoked: void;
}>;
type AddressInput = {
    bits: string;
};
type AddressOutput = AddressInput;
type AssetIdInput = {
    bits: string;
};
type AssetIdOutput = AssetIdInput;
type BuyerOutput = {
    buyer: IdentityOutput;
    quantity_bought: BN;
    buy_price_per_item: BN;
};
type ContractIdInput = {
    bits: string;
};
type ContractIdOutput = ContractIdInput;
type ListingOutput = {
    order_id: BN;
    seller: IdentityOutput;
    nft_contract: ContractIdOutput;
    asset_id: AssetIdOutput;
    token_id: string;
    price: BN;
    quantity: BN;
    standard: NFTStandardOutput;
};
declare class NftMarketplaceInterface extends Interface {
    constructor();
    functions: {
        owner: FunctionFragment;
        buy_nft: FunctionFragment;
        cancel_listing: FunctionFragment;
        change_admin: FunctionFragment;
        get_admin_fee: FunctionFragment;
        get_buyers: FunctionFragment;
        get_commission_percentage: FunctionFragment;
        get_current_listing_id: FunctionFragment;
        get_listing: FunctionFragment;
        has_user_listed_nft_before: FunctionFragment;
        init: FunctionFragment;
        list_nft: FunctionFragment;
        modify_listing: FunctionFragment;
        set_admin_fee: FunctionFragment;
        set_commission_percentage: FunctionFragment;
        withdraw_funds: FunctionFragment;
    };
}
declare class NftMarketplace extends Contract {
    static readonly abi: {
        programType: string;
        specVersion: string;
        encodingVersion: string;
        concreteTypes: ({
            type: string;
            concreteTypeId: string;
            metadataTypeId?: undefined;
            typeArguments?: undefined;
        } | {
            type: string;
            concreteTypeId: string;
            metadataTypeId: number;
            typeArguments?: undefined;
        } | {
            type: string;
            concreteTypeId: string;
            metadataTypeId: number;
            typeArguments: string[];
        })[];
        metadataTypes: ({
            type: string;
            metadataTypeId: number;
            components: ({
                name: string;
                typeId: string;
            } | {
                name: string;
                typeId: number;
            })[];
            typeParameters?: undefined;
        } | {
            type: string;
            metadataTypeId: number;
            components: ({
                name: string;
                typeId: string;
            } | {
                name: string;
                typeId: number;
            })[];
            typeParameters: number[];
        } | {
            type: string;
            metadataTypeId: number;
            components?: undefined;
            typeParameters?: undefined;
        } | {
            type: string;
            metadataTypeId: number;
            components: ({
                name: string;
                typeId: number;
                typeArguments: {
                    name: string;
                    typeId: number;
                }[];
            } | {
                name: string;
                typeId: string;
                typeArguments?: undefined;
            })[];
            typeParameters: number[];
        })[];
        functions: {
            inputs: {
                name: string;
                concreteTypeId: string;
            }[];
            name: string;
            output: string;
            attributes: {
                name: string;
                arguments: string[];
            }[];
        }[];
        loggedTypes: {
            logId: string;
            concreteTypeId: string;
        }[];
        messagesTypes: never[];
        configurables: never[];
    };
    static readonly storageSlots: StorageSlot[];
    interface: NftMarketplaceInterface;
    functions: {
        owner: InvokeFunction<[], StateOutput>;
        buy_nft: InvokeFunction<[listing_id: BigNumberish, quantity: BigNumberish], void>;
        cancel_listing: InvokeFunction<[listing_id: BigNumberish], void>;
        change_admin: InvokeFunction<[new_owner: IdentityInput], void>;
        get_admin_fee: InvokeFunction<[], BN>;
        get_buyers: InvokeFunction<[listing_id: BigNumberish], Vec<BuyerOutput>>;
        get_commission_percentage: InvokeFunction<[contract_id: ContractIdInput], BN>;
        get_current_listing_id: InvokeFunction<[], BN>;
        get_listing: InvokeFunction<[listing_id: BigNumberish], Option<ListingOutput>>;
        has_user_listed_nft_before: InvokeFunction<[user: IdentityInput, contract_id: ContractIdInput, asset: AssetIdInput], boolean>;
        init: InvokeFunction<[admin: IdentityInput], void>;
        list_nft: InvokeFunction<[nft_contract_id: ContractIdInput, price: BigNumberish, token_id: string, quantity: BigNumberish, standard: NFTStandardInput], void>;
        modify_listing: InvokeFunction<[listing_id: BigNumberish, new_price: BigNumberish, qtyToAdd: BigNumberish], void>;
        set_admin_fee: InvokeFunction<[fee: BigNumberish], void>;
        set_commission_percentage: InvokeFunction<[nft_contract_id: ContractIdInput, percentage: BigNumberish, asset_id: AssetIdInput], void>;
        withdraw_funds: InvokeFunction<[], void>;
    };
    constructor(id: string | AbstractAddress, accountOrProvider: Account | Provider);
}

declare class BuyTokenService extends MarketplaceServices {
    private readonly contract;
    private readonly wallet;
    private listingId;
    private quantity;
    private pricePerItem;
    constructor(contract: NftMarketplace, wallet: Account);
    setProperties(listingId: `0x${string}`, quantity: number, pricePerItem: number): this;
    execute(): Promise<{
        success: boolean;
        data: fuels.FunctionResult<void>;
        error?: undefined;
    } | {
        success: boolean;
        error: unknown;
        data?: undefined;
    }>;
}

declare class CancelListingService extends MarketplaceServices {
    private readonly contract;
    private listingId;
    constructor(contract: NftMarketplace);
    setProperties(listingId: `0x${string}`): this;
    execute(): Promise<{
        success: boolean;
        data: fuels.FunctionResult<void>;
        error?: undefined;
    } | {
        success: boolean;
        error: unknown;
        data?: undefined;
    }>;
}

declare class ListTokenService extends MarketplaceServices {
    private readonly contract;
    private assetId;
    private contractAddress;
    private subId;
    private price;
    private amount;
    private tokenStandard;
    constructor(contract: NftMarketplace);
    setProperties(assetId: `0x${string}`, contractAddress: `0x${string}`, subId: `0x${string}`, price: number, amount: number, tokenStandard: NFTStandardInput): this;
    execute(): Promise<{
        success: boolean;
        data: fuels.FunctionResult<void>;
        error?: undefined;
    } | {
        success: boolean;
        error: unknown;
        data?: undefined;
    } | null>;
}

declare class ModifyListingService extends MarketplaceServices {
    private readonly contract;
    private assetId;
    private listingId;
    private newPrice;
    private quantityToAdd;
    constructor(contract: NftMarketplace);
    setProperties(listingId: `0x${string}`, newPrice: number, quantityToAdd: number, assetId?: `0x${string}`): this;
    execute(): Promise<{
        success: boolean;
        data: fuels.FunctionResult<void>;
        error?: undefined;
    } | {
        success: boolean;
        error: unknown;
        data?: undefined;
    }>;
}

declare class MarketplaceClient {
    private readonly contract;
    private readonly wallet;
    constructor(network: Networks, wallet: Account);
    useBuyTokenService(): BuyTokenService;
    useCancelListingService(): CancelListingService;
    useListTokenService(): ListTokenService;
    useModifyListingService(): ModifyListingService;
}

declare const searchMarketplace: (network: Networks, searchString: string, limit?: number) => Promise<{
    success: boolean;
    data: TData;
    error?: undefined;
} | {
    success: boolean;
    error: unknown;
    data?: undefined;
} | {
    success: boolean;
    data: MarketplaceListings[];
}>;

declare const checkNftOwnership: (wallet: Account, contractAddress: `0x${string}`, subId: `0x${string}`, nftStandard: "NFT" | "SEMI_FT") => Promise<{
    success: boolean;
    data: {
        contractAddress: `0x${string}`;
        subId: `0x${string}`;
        nftStandard: "NFT" | "SEMI_FT";
    };
    errors?: undefined;
} | {
    success: boolean;
    errors: any[];
    data?: undefined;
}>;

declare const getAllNftsInCollection: ({ network, nftStandard, contractAddress, }: AllNftsInCollectionArgs) => Promise<{
    success: true;
    data: TokensInCollection[];
} | {
    success: false;
    error: unknown;
}>;

declare const getCollections: ({ network, limit, }: HooksArgs) => Promise<{
    success: true;
    data: MarketplaceCollections[];
} | {
    success: false;
    error: unknown;
}>;

declare const getListings: ({ network, limit, }: HooksArgs) => Promise<{
    success: true;
    data: MarketplaceListings[];
} | {
    success: false;
    error: unknown;
}>;

declare const getNftDetails: ({ network, limit, contractAddress, nftStandard, tokenId, }: NftDetailsArgs) => Promise<{
    success: true;
    data: NftDetails;
} | {
    success: false;
    error: unknown;
}>;

export { AllowedProviders, MarketplaceClient, type MarketplaceCollections, MarketplaceError, MarketplaceErrorCodes, type MarketplaceListings, Networks, type NftDetails, type NftMetadata, type OmittedMarketplaceListings, type TokensInCollection, checkNftOwnership, getAllNftsInCollection, getCollections, getListings, getNftDetails, searchMarketplace, useAllNftsInCollection, useCollections, useListings, useNft };
