import type { SupportedChain } from '../chains.js';
import type { CrossChainOrder } from '../core/orders/cross-chain.js';
import type { ExtraTransfer } from '../core/orders/common.js';
import type { SingleChainOrder } from '../core/orders/single-chain.js';

/**
 * Details required to execute the order on the destination chain
 * Contains all information needed for the cross-chain fulfillment
 */
export type ExecutionDetails = {
  /** Chain ID where tokens will be received */
  destChainId: SupportedChain;
  /** Token address on the destination chain to receive */
  tokenOut: string;
  /** Minimum amount of destination tokens to receive, in smallest units */
  amountOutMin: bigint;
  /** Recipient wallet address on the destination chain */
  destinationAddress: string;
  /** Extra transfers to be made */
  extraTransfers?: ExtraTransfer[];
};

export type Hash = `0x${string}`;
/** Hash of execution details, used to verify order integrity across chains */
export type ExecutionDetailsHash = Hash;

export type EvmPreparedData = {
  /** Random nonce for Permit2 signature, prevents replay attacks */
  nonce: string;
  /** EIP-712 signature authorizing the order */
  signature: string | Hash;
};

export type SuiPreparedData = {
  /** Transaction hash of the successful order creation transaction */
  transactionHash: string;
};

export type SolanaPreparedData = {
  /** Public key of the created order account on Solana */
  orderPubkey: string;
};

/**
 * Source chain data sent to the auctioneer
 * Contains all information needed to start the cross-chain swap from the source chain
 */
export type SourceChainData = {
  /** User's wallet address that initiated the order */
  user: string;
  /** Source chain ID where tokens will be sent from */
  srcChainId: SupportedChain;
  /** Token address on the source chain to be swapped */
  tokenIn: string;
  /** Amount of source tokens to swap, in smallest units */
  amountIn: bigint;
  /** Minimum amount of stablecoins in the intermediate swap, in smallest units */
  minStablecoinsAmount: bigint;
  /** Timestamp (in seconds) after which the order expires */
  deadline: number;
  /** Hash of execution details for cross-chain verification */
  executionDetailsHash: ExecutionDetailsHash;
  stopLossMaxOut?: bigint;
  takeProfitMinOut?: bigint;
  extraTransfers?: ExtraTransfer[];
};

export type CrossChainUserIntentRequest = {
  /** Generic data common to all chains */
  genericData: SourceChainData;
  /** JSON-stringified execution details for the destination chain */
  executionDetails: string;
  /** Chain-specific data including signatures and transaction details */
  chainSpecificData: {
    /** EVM-specific data (for Ethereum, Arbitrum, Optimism, Base) */
    EVM?: EvmPreparedData;
    /** Solana-specific data */
    Solana?: SolanaPreparedData;
    /** Sui-specific data */
    Sui?: SolanaPreparedData;
  };
};

export type SingleChainUserIntentRequest = {
  genericData: SingleChainOrder;
  chainSpecificData: {
    EVM?: EvmPreparedData;
    Solana?: SolanaPreparedData;
    Sui?: SolanaPreparedData;
  };
};

export type ChainPreparedData = EvmPreparedData | SuiPreparedData | SolanaPreparedData;

export type CrossChainOrderPrepared = {
  order: CrossChainOrder;
  preparedData: ChainPreparedData;
};

export type SingleChainEVMPreparedData = {
  nonce: string;
  signature: string | Hash;
};

export type SingleChainSolanaPreparedData = {
  secretNumber: string;
  orderPubkey: string;
};

export type SingleChainSuiPreparedData = {
  transactionHash: string;
};

export type SingleChainPreparedData =
  | SingleChainEVMPreparedData
  | SingleChainSolanaPreparedData
  | SingleChainSuiPreparedData;

export type SingleChainOrderPrepared = {
  order: SingleChainOrder;
  preparedData: SingleChainPreparedData;
};
