import { Address } from 'viem';
import { EVM } from '@lifi/sdk';
import { LiFiStep } from '@lifi/sdk';
import { RouteExtended } from '@lifi/sdk';
import { SDKProvider } from '@lifi/sdk';

export declare const config: {
    get(): SDKConfig;
    set(configOptions: Partial<SDKConfig>): SDKConfig;
};

export declare type ConfigOptions = Partial<SDKConfig> & {
    integrator: SDKConfig["integrator"];
};

export declare type ConfigResponse = {
    chains: Array<{
        id: number;
        name: string;
    }>;
    fiatCurrencies: Array<FiatCurrency>;
    providers: Array<Provider & {
        tokens: Array<{
            type: RouteType;
            token: Token;
        }>;
    }>;
    tokens: Array<Token>;
};

export declare function createOnRampConfig(configOptions: ConfigOptions): SDKConfig;

export { EVM }

export declare function executeRoute(quote: UnexecutedRoute | Route, executionOptions?: ExternalExecutionOptions): Promise<Route>;

export declare interface Execution {
    status: ExecutionStatus;
    message?: string;
    process: Process[];
    [key: string]: unknown;
}

declare type ExecutionStatus = "ACTION_REQUIRED" | "PENDING" | "FAILED" | "DONE";

export declare type ExternalExecutionOptions = {
    onUpdateHook?: (route: Route) => void;
    executeInBackground?: boolean;
};

export declare function fetchConfig(): Promise<ConfigResponse>;

export declare type FetchQuoteParams = {
    toAddress: Address;
    fiatAmount?: number;
    fiatCurrency?: SupportedFiatCurrencies;
    chainId: number;
    toToken: Address;
    tokenAmount?: number;
    providerTypes?: QuoteProviderType[];
    paymentMethods?: PaymentMethod[];
    routeType?: "buy" | "sell";
    country?: string;
};

export declare function fetchQuotes(params: FetchQuoteParams): Promise<QuotesResponse>;

declare type FiatCurrency = typeof supportedFiatCurrencies[number];

/**
 * Filters provider quotes based on payment method types.
 * Can either include only specified payment methods or exclude specified payment methods.
 * Removes any provider quotes that end up with no payment methods after filtering.
 *
 * @param providerQuotes - The array of provider quotes to filter
 * @param paymentMethods - The array of payment method types to include or exclude
 * @param filterType - Determines whether to include or exclude the specified payment methods (default: "include")
 * @returns A new array of filtered provider quotes
 */
export declare function filterByPaymentMethod(providerQuotes: ProviderQuoteOption[], paymentMethods: PaymentMethod[], filterType?: "include" | "exclude"): ProviderQuoteOption[];

declare enum KycRequirement {
    NO_KYC = "no_kyc",
    BASIC = "basic",
    DOCUMENT_BASED = "document_based"
}

export declare type PaymentMethod = `${PaymentMethod_2}`;

declare enum PaymentMethod_2 {
    APPLE_PAY_CREDIT = "apple_pay_credit",
    GOOGLE_PAY_CREDIT = "google_pay_credit",
    APPLE_PAY_DEBIT = "apple_pay_debit",
    GOOGLE_PAY_DEBIT = "google_pay_debit",
    CREDIT_CARD = "credit_card",
    DEBIT_CARD = "debit_card",
    WIRE = "wire",
    PIX = "pix",
    SEPA = "sepa",
    ACH = "ach",
    KOYWE = "koywe"
}

declare interface PaymentMethodQuote {
    method: PaymentMethod_2;
    pay: {
        currency: string;
        fiatAmount: number;
        totalFeeFiat: number;
        minAmountUnits?: string;
        minAmountFiat?: number;
        maxAmountUnits?: string;
        maxAmountFiat?: number;
    };
    receive: {
        token: Token;
        chain: {
            id: number;
            name: string;
        };
        to: Address;
        amountUnits: string;
        amountFiat: number;
    };
    kyc: KycRequirement[];
    steps: QuoteStep[];
}

export declare type Process = {
    type: ProcessType;
    message: string;
    status: ProcessStatus;
    substatus?: Substatus;
    [key: string]: any;
};

export declare type ProcessStatus = "PENDING" | "ACTION_REQUIRED" | "PERMIT_REQUIRED" | "DONE" | "FAILED" | "CANCELLED";

export declare type ProcessType = "EXTERNAL" | "STATUS_CHECK";

export declare type Provider = {
    key: string;
    type: QuoteProviderType_2;
    name: string;
    iconUrl: string;
};

export declare interface ProviderQuoteOption {
    id?: string;
    type: `${RouteType}`;
    provider: Provider;
    country?: string;
    paymentMethods: PaymentMethodQuote[];
}

export declare type QuoteProviderType = "cex" | "onramp";

declare enum QuoteProviderType_2 {
    CEX = "cex",
    ONRAMP = "onramp"
}

export declare type QuotesResponse = {
    quotes: ProviderQuoteOption[];
};

declare type QuoteStep = QuoteStepOnrampViaLink | QuoteStepTokenSwap;

declare type QuoteStepOnrampViaLink = {
    id?: string;
    type: "onramp_via_link";
    link: string;
};

declare type QuoteStepTokenSwap = {
    type: "lifi_token_swap";
    swapQuote: LiFiStep;
};

export declare function quoteToRoute(type: `${RouteType}`, quote: ProviderQuoteOption["paymentMethods"][0], provider: ProviderQuoteOption["provider"]): UnexecutedRoute;

export declare function resumeRouteExecution(route: Route, executionOptions?: ExternalExecutionOptions): Promise<Route>;

export declare interface Route extends Omit<ProviderQuoteOption, "paymentMethods">, Omit<PaymentMethodQuote, "steps"> {
    id: string;
    status: "HALTING" | "HALTED" | "RUNNING" | "DONE";
    steps: StepExtended[];
}

declare enum RouteType {
    BUY = "buy",
    SELL = "sell"
}

export declare type SDKConfig = {
    /**
     * A plain string that identifies the integrator.
     */
    integrator: string;
    /**
     * The URL for the API endpoint that the on-ramp SDK
     * will use to request quotes and SDK config settings.
     *
     * By default it will use the production URL,
     * but you can set it to a custom URL for testing purposes.
     *
     * If you want to use the development mode which uses
     * sandbox URLs from services to generate quotes,
     * you can set the `dev` flag to `true`.
     */
    apiUrl?: string;
    /**
     * The list of services to be used for the onramp.
     *
     * If no services are defined,
     * or if none of the keys are valid in the array,
     * all services will be provided for quotes.
     */
    services: Services[];
    /**
     * The provider configuration to handle wallet
     * transactions and chain switching via the on-ramp.
     */
    provider: SDKProvider | null;
    /**
     * Setting the `dev` flag to `true` will
     * enable the development mode for the SDK.
     *
     * This will use sandbox URLs from services to
     * generate quotes.
     */
    dev?: boolean;
};

export { SDKProvider }

export declare type Services = "transak";

/**
 * Sorts provider quotes by fee amount either within each provider or across all providers.
 *
 * @param providerQuotes - An array of provider quote options to be sorted
 * @param group - Whether to maintain the grouping of payment methods by provider (true) or
 *                flatten and sort across all providers (false)
 * @param order - Sort order: 'asc' for ascending (lower fees first) or 'desc' for descending (higher fees first)
 * @returns A new array of provider quote options with payment methods sorted by fees
 */
export declare function sortByFees(providerQuotes: ProviderQuoteOption[], group?: boolean, order?: "asc" | "desc"): ProviderQuoteOption[];

/**
 * Sorts a list of provider quotes by the highest return value in fiat currency among
 * all the providers.
 *
 * This function takes an array of `ProviderQuoteOption` objects, where each provider
 * may have multiple payment methods. It flattens the array by creating a new object
 * for each payment method, retaining the provider's other properties. The resulting
 * array is then sorted in ascending order based on the `amountFiat` value of the
 * first payment method in each provider's payment methods array.
 *
 * @param providerQuotes - An array of `ProviderQuoteOption` objects, each containing
 *                         a list of payment methods with associated fiat return values.
 * @returns A new array of `ProviderQuoteOption` objects, each containing a single
 *          payment method, sorted by the highest fiat return value.
 */
export declare function sortByHighestReturn(providerQuotes: ProviderQuoteOption[]): ProviderQuoteOption[];

/**
 * Sorts an array of provider quotes by arranging the payment methods of each provider
 * in descending order based on the `amountFiat` value in the `receive` property.
 *
 * @param providerQuotes - An array of provider quote options to be sorted.
 * @returns A new array of provider quote options with their payment methods sorted
 *          by the `amountFiat` value in descending order.
 */
export declare function sortProviderQuotes(providerQuotes: ProviderQuoteOption[]): ProviderQuoteOption[];

export declare interface Step {
    type: "onramp_via_link" | "lifi_token_swap";
    [key: string]: unknown;
}

export declare interface StepExtended extends Step {
    id: string;
    execution: Execution;
    swapQuote?: LiFiStep;
    lifiRoute?: RouteExtended;
    [key: string]: unknown;
}

export declare function stopRouteExecution(routeId: Route["id"]): void;

declare type Substatus = {
    message: string;
    action: string;
};

export declare type SupportedFiatCurrencies = "USD";

declare const supportedFiatCurrencies: readonly ["USD"];

declare type Token = {
    chainId: number;
    address: Address;
    decimals: number;
    symbol: string;
    name: string;
    usdPrice: number;
    marketCap: number;
    iconUrl?: string;
};

export declare interface UnexecutedRoute extends Omit<ProviderQuoteOption, "paymentMethods"> {
    steps: Step[];
}

export declare function updateRouteExecution(route: Route, executionOptions: ExternalExecutionOptions): void;

export { }
