import { BigNumberish, BigNumber } from 'ethers';
import { TransactionRequest } from '@ethersproject/providers';

type ApiOverrides = {
    apiUrl?: string;
};

declare enum Web3Environment {
    DEVNET = "devnet",
    TESTNET = "testnet",
    MAINNET = "mainnet"
}

type Token = {
    address: string;
    name: string;
    symbol: string;
    decimals: number;
};

type Chain = {
    ecosystem: string;
    chainId: string;
    name: string;
    displayName: string;
    web3Environment: Web3Environment;
    transactionExplorer: string;
    rpcUrls?: Array<string>;
    ccipChainId: string;
    tokens: Token[];
};

type CoinTypeAddress = {
    coinType: number;
    address: string;
};

type CollectFees = {
    integratorAddress: string;
    fee: number;
};

declare enum XSwapCallType {
    DEFAULT = 0,
    FULL_TOKEN_BALANCE = 1,
    FULL_NATIVE_BALANCE = 2,
    COLLECT_TOKEN_BALANCE = 3
}

type ContractCall = {
    callType: XSwapCallType;
    target: string;
    value: string;
    callData: string;
    payload: string;
    estimatedGas?: string;
};

declare enum Ecosystem {
    EVM = "evm"
}

declare enum Environment {
    PROD = "production",
    DEV = "develop",
    LOCAL = "local"
}

type GetRoutePayload = {
    fromChain: string;
    toChain: string;
    fromToken: string;
    toToken: string;
    fromAmount: string;
    fromAddress: string;
    toAddress: string;
    paymentToken: string;
    slippage: number;
    expressDelivery: boolean;
    quoteOnly?: boolean;
    enableExpress?: boolean;
    customContractCalls?: ContractCall[];
    sourceChainDexes?: string[];
    destinationChainDexes?: string[];
    receiveGasOnDestination?: boolean;
    collectFees?: CollectFees;
    fallbackAddresses?: CoinTypeAddress[];
};

type AddReferralPayload = {
    code: string;
    address: string;
};

type Protocol = {
    name: string;
    part: number;
    fromTokenAddress: string;
    toTokenAddress: string;
};

type XSwapFee = {
    tokenFee: string;
    nativeFee: string;
};

type XSwapFees = {
    ccipFee: string;
    xSwapFee: XSwapFee;
    expressDeliveryFee: string;
};

type Route = {
    originChainXSwapCalls: ContractCall[];
    originProtocols: Protocol[][][];
    destinationChainXSwapCalls: ContractCall[];
    destinationProtocols: Protocol[][][];
    originCrossChainTransferToken: string;
    destinationCrossChainTransferToken: string;
    amountToTransferCrossChain: BigNumberish;
    estAmountOut: string;
    minAmountOut: string;
    estimatedGasDestination: number;
    transaction: TransactionRequest;
    xSwapFees: XSwapFees;
};

type Referral = {
    address: string;
    code: string;
    referrals: ReferralInfo[];
};
type ReferralInfo = {
    address: string;
    ipAddress: string;
};

declare const DEFAULT_API_URL = "https://xswap.link/api";
declare const DEFAULT_DB_ERROR = "No data for provided parameters";
declare const DEFAULT_ECOSYSTEM = Ecosystem.EVM;
declare const DEFAULT_NATIVE_FEE_MULTIPLIER_PERCENTAGE = 105;

declare const XSwapRouterAbi: ({
    inputs: never[];
    stateMutability: string;
    type: string;
    name?: undefined;
    anonymous?: undefined;
    outputs?: undefined;
} | {
    inputs: {
        internalType: string;
        name: string;
        type: string;
    }[];
    name: string;
    type: string;
    stateMutability?: undefined;
    anonymous?: undefined;
    outputs?: undefined;
} | {
    anonymous: boolean;
    inputs: {
        indexed: boolean;
        internalType: string;
        name: string;
        type: string;
    }[];
    name: string;
    type: string;
    stateMutability?: undefined;
    outputs?: undefined;
} | {
    inputs: ({
        internalType: string;
        name: string;
        type: string;
        components?: undefined;
    } | {
        components: ({
            internalType: string;
            name: string;
            type: string;
            components?: undefined;
        } | {
            components: {
                internalType: string;
                name: string;
                type: string;
            }[];
            internalType: string;
            name: string;
            type: string;
        })[];
        internalType: string;
        name: string;
        type: string;
    })[];
    name: string;
    outputs: {
        components: ({
            internalType: string;
            name: string;
            type: string;
            components?: undefined;
        } | {
            components: {
                internalType: string;
                name: string;
                type: string;
            }[];
            internalType: string;
            name: string;
            type: string;
        })[];
        internalType: string;
        name: string;
        type: string;
    }[];
    stateMutability: string;
    type: string;
    anonymous?: undefined;
} | {
    inputs: ({
        internalType: string;
        name: string;
        type: string;
        components?: undefined;
    } | {
        components: ({
            internalType: string;
            name: string;
            type: string;
            components?: undefined;
        } | {
            components: {
                internalType: string;
                name: string;
                type: string;
            }[];
            internalType: string;
            name: string;
            type: string;
        })[];
        internalType: string;
        name: string;
        type: string;
    })[];
    name: string;
    outputs: {
        internalType: string;
        name: string;
        type: string;
    }[];
    stateMutability: string;
    type: string;
    anonymous?: undefined;
} | {
    stateMutability: string;
    type: string;
    inputs?: undefined;
    name?: undefined;
    anonymous?: undefined;
    outputs?: undefined;
})[];

declare const safeBigNumberFrom: (value: string) => BigNumber;

export { type AddReferralPayload, type ApiOverrides, type Chain, type CoinTypeAddress, type CollectFees, type ContractCall, DEFAULT_API_URL, DEFAULT_DB_ERROR, DEFAULT_ECOSYSTEM, DEFAULT_NATIVE_FEE_MULTIPLIER_PERCENTAGE, Ecosystem, Environment, type GetRoutePayload, type Protocol, type Referral, type ReferralInfo, type Route, type Token, Web3Environment, XSwapCallType, type XSwapFee, type XSwapFees, XSwapRouterAbi, safeBigNumberFrom };
