import { Input, Output, RouteDetails, Token } from '../../../../types/index';
import { TransactionInstruction } from '@solana/web3.js';
import { SOLANA_CHAIN_ID } from '../../../../utils/constants';
import { Address } from 'viem';

export type BungeeQuote = {
    originChainId: number;
    destinationChainId: number;
    userAddress: string;
    receiverAddress: string;
    input: Input;
    destinationExec: string | null;
    autoRoute: AutoRoute;
    manualRoutes: ManualRoute[];
};
type AutoRoute = {
    userOp: "sign" | "tx";
    output: {
        token: Token;
        priceInUsd: number;
        valueInUsd: number;
        minAmountOut: string;
        amount: string;
        effectiveReceivedInUsd: number;
    };
    requestType: RequestType;
    requestHash: string;
    approvalData: ApprovalData | null;
    affiliateFee: string | null;
    slippage: number;
    suggestedClientSlippage: number;
    signTypedData: SignTypedData;
    refuel: AutoRefuel | null;
    txData: TxData | null;
    quoteId: string;
    quoteExpiry: number;
    rewards?: Rewards;
    estimatedTime: number;
    gasFee: GasFee | null;
    routeDetails: RouteDetails;
};
type ManualRoute = {
    quoteId: string;
    quoteExpiry: number;
    output: {
        token: Token;
        amount: string;
        priceInUsd: number;
        valueInUsd: number;
        minAmountOut: string;
        effectiveReceivedInUsd: number;
    };
    affiliateFee: string | null;
    approvalData: ApprovalData;
    gasFee: GasFee;
    slippage: number;
    estimatedTime: number;
    routeDetails: RouteDetails;
    refuel: ManualRefuel | null;
};
export type GasFee = {
    gasToken: Token;
    gasLimit: string;
    gasPrice: string;
    estimatedFee: string;
    feeInUsd: number;
};
export type AutoRefuel = {
    output: RefuelEndpoint;
};
export type ManualRefuel = {
    input: RefuelEndpoint;
    output: RefuelEndpoint;
};
export type RefuelEndpoint = {
    token: Token;
    amount: string;
};
type BaseFormattedQuote = {
    routingMode: "auto" | "manual";
    receiver: string;
    sender: string;
    input: Input[];
    output: Output[];
    primaryInput: Input;
    primaryOutput: Output;
    estimatedFulfilTime: number;
    isSwapRoute: boolean;
    srcToDestRate?: number;
    destToSrcRate?: number;
    slippage: number | null;
    minOutput?: {
        amount: string;
        formattedAmount: string;
        valueInUsd?: number;
    };
    approvalData: ApprovalData | null;
    refuel: AutoRefuel | ManualRefuel | null;
};
export type FormattedAutoQuote = BaseFormattedQuote & {
    routingMode: "auto";
    requestHash: string;
    requestType: RequestType;
    signTypedData: SignTypedData;
    txData: TxData | null;
    userOp: "sign" | "tx";
    quoteId: string;
    rewards?: Rewards;
    refuel: AutoRefuel | null;
    gasFee: GasFee | null;
    suggestedClientSlippage: number;
};
export type FormattedManualQuote = BaseFormattedQuote & {
    routingMode: "manual";
    protocol: RouteDetails;
    totalGasFeesInUsd: number;
    routeId: string;
    receivedValueInUsd: number;
    refuel: ManualRefuel | null;
    gasFee: GasFee;
    slippage: number;
};
export type FormattedQuoteResponse = FormattedAutoQuote | FormattedManualQuote;
export type RequestType = "SWAP_REQUEST" | "SINGLE_OUTPUT_REQUEST";
export type TxData<T extends typeof SOLANA_CHAIN_ID | number = number> = {
    data: T extends typeof SOLANA_CHAIN_ID ? {
        instructions: TransactionInstruction[];
        signers: number[][];
        lookupTables: string[];
    } : Address;
    to: Address;
    chainId: T;
    value: bigint;
};
export type OrderFlowType<T extends string | undefined = undefined> = "bundled" | "regular" | (T & {});
export interface ApprovalData {
    amount: string;
    spenderAddress: string;
    tokenAddress: string;
    userAddress: string;
}
export interface SignTypedData {
    domain: {
        name: string;
        chainId: number;
        verifyingContract: Address;
    };
    types: {
        PermitWitnessTransferFrom: Array<{
            name: string;
            type: string;
        }>;
        TokenPermissions: Array<{
            name: string;
            type: string;
        }>;
        Request: Array<{
            name: string;
            type: string;
        }>;
        BasicRequest: Array<{
            name: string;
            type: string;
        }>;
    };
    values: {
        permitted: {
            token: Address;
            amount: string;
        };
        spender: Address;
        nonce: string;
        deadline: string;
        witness: {
            basicReq: {
                originChainId: number;
                destinationChainId: number;
                deadline: string;
                nonce: string;
                sender: Address;
                receiver: Address;
                delegate: Address;
                bungeeGateway: Address;
                switchboardId: number;
                inputToken: Address;
                inputAmount: string;
                outputToken: Address;
                minOutputAmount: string;
                refuelAmount: string;
            };
            swapOutputToken: Address;
            minSwapOutput: string;
            metadata: Address;
            affiliateFees: Address;
            minDestGas: string;
            destinationPayload: Address;
            exclusiveTransmitter: Address;
        };
    };
}
export type Rewards = {
    rebateAmount: string;
    rewardAmount: string;
    totalRewardAmount: string;
    totalRewardAmountInUsd: number;
    token: Token;
    isRewardEnabled?: boolean;
};
export {};
